In [1]:
import numpy as np 
import glob
import os
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import cv2
%matplotlib inline

Camera Calibration

In [2]:
# First calibrate the camera
CALIBRATION_FOLDER_NAME = "camera_cal"

# read in the images
images_path = glob.glob(os.path.join(CALIBRATION_FOLDER_NAME, "calibration*.jpg"))
print(images_path) 
['camera_cal/calibration10.jpg', 'camera_cal/calibration11.jpg', 'camera_cal/calibration12.jpg', 'camera_cal/calibration13.jpg', 'camera_cal/calibration14.jpg', 'camera_cal/calibration15.jpg', 'camera_cal/calibration16.jpg', 'camera_cal/calibration17.jpg', 'camera_cal/calibration18.jpg', 'camera_cal/calibration19.jpg', 'camera_cal/calibration2.jpg', 'camera_cal/calibration20.jpg', 'camera_cal/calibration21.jpg', 'camera_cal/calibration3.jpg', 'camera_cal/calibration4.jpg', 'camera_cal/calibration5.jpg', 'camera_cal/calibration6.jpg', 'camera_cal/calibration7.jpg', 'camera_cal/calibration8.jpg', 'camera_cal/calibration9.jpg']
In [3]:
# Look at an image to see how many corners are in the chessboard 
test_image = mpimg.imread(images_path[np.random.randint(len(images_path))])
plt.imshow(test_image)
Out[3]:
<matplotlib.image.AxesImage at 0x113961d30>
In [4]:
# Define the number of corners
nx = 9
ny = 6

# define the object points, these are the points that are on the chessboard
objp = np.zeros((ny * nx, 3), np.float32)
objp[:,:2] = np.mgrid[0:nx, 0:ny].T.reshape(-2, 2) # x, y coordinates
In [5]:
# Now define the corners on the images
# The goal here is to map the imgpoints (which are the coordinates on the image) to our 
# predefined world coordinates

imgpoints = [] # these are the 3D points in the real world space
objpoints = [] # these are the 2D points in the image plane
chessboards_with_drawn_corners = []

for image_path in images_path:
    # if matplotlib is used
    image = mpimg.imread(image_path)
    gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
    
    
    # if cv2 is used although we don't use it to plot as it can't plot inline
#     image = cv2.imread(image_path)
#     print(image)
#     break
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # note that we use BGR2GRAY 
    
    ret, corners = cv2.findChessboardCorners(gray, (nx, ny), None)
    
    if ret == True:
        imgpoints.append(corners)
        objpoints.append(objp) 
        chessboard_with_drawn_corners = cv2.drawChessboardCorners(image, (nx, ny), corners, ret)
        chessboards_with_drawn_corners.append(chessboard_with_drawn_corners) 
        
#         cv2.imshow('img', chessboard_with_drawn_corners)
#         cv2.waitKey(500)
In [6]:
# Plot the chessboard with the corners drawn
plt.imshow(chessboards_with_drawn_corners[np.random.randint(len(chessboards_with_drawn_corners))])
Out[6]:
<matplotlib.image.AxesImage at 0x113eba588>
In [7]:
# Finally calibrate the camera
test_image_path = os.path.join(CALIBRATION_FOLDER_NAME, "test_for_calibration.jpg")
test_image = plt.imread(test_image_path)
test_image_size = (test_image.shape[1], test_image.shape[0])
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, test_image_size, None, None)
In [8]:
# Plot test image before applying undistorting
plt.imshow(test_image)
Out[8]:
<matplotlib.image.AxesImage at 0x11528c780>
In [9]:
# Plot test image after applying undistortion
dest = cv2.undistort(test_image, mtx, dist, None, mtx)
plt.imshow(dest)
Out[9]:
<matplotlib.image.AxesImage at 0x115930a90>
In [10]:
# Now lets aggregate these into a function

def calibrate_camera(calibration_image_paths, test_image_path, nx, ny):
    """
    The purpose of this function is to calibrate the camera, it returns the coordinate matrix
    and the distortion matrix
    :::params calibration_image_paths : the path of where the images are stored
              test_image_path : the path of the test image
              nx : number of corners in the x direction
              ny : number of corners in the y direction
              
    """
    # define the object points, these are the points that are on the chessboard
    objp = np.zeros((ny * nx, 3), np.float32)
    objp[:,:2] = np.mgrid[0:nx, 0:ny].T.reshape(-2, 2) # x, y coordinates
    
    # define the image points, these are the points that are in the real world
    # The goal here is to map the imgpoints (which are the coordinates on the image) to our 
    # predefined world coordinates

    imgpoints = [] # these are the 3D points in the real world space
    objpoints = [] # these are the 2D points in the image plane
    chessboards_with_drawn_corners = []

    for image_path in calibration_image_paths:
        
        # if matplotlib is used
        image = mpimg.imread(image_path)
        gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)


        # if cv2 is used although we don't use it to plot as it can't plot inline
    #     image = cv2.imread(image_path)
    #     print(image)
    #     break
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # note that we use BGR2GRAY 

        ret, corners = cv2.findChessboardCorners(gray, (nx, ny), None)

        if ret == True:
            imgpoints.append(corners)
            objpoints.append(objp) 
            chessboard_with_drawn_corners = cv2.drawChessboardCorners(image, (nx, ny), corners, ret)
            chessboards_with_drawn_corners.append(chessboard_with_drawn_corners)
        
    ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, test_image_size, None, None)
    return mtx, dist
In [11]:
# test it
CALIBRATION_FOLDER_NAME = "camera_cal"

# image paths for calibration images
calibration_image_paths = glob.glob(os.path.join(CALIBRATION_FOLDER_NAME, "calibration*.jpg"))

# image path for test image
test_image_path = os.path.join(CALIBRATION_FOLDER_NAME, "test_for_calibration.jpg")

# For the parameters for the calibration
mtx, dist = calibrate_camera(calibration_image_paths, test_image_path, 9, 6)
In [12]:
# plot the undistorted image
test_image = mpimg.imread(test_image_path)
dest = cv2.undistort(test_image, mtx, dist, None, mtx)
In [13]:
f, (ax1, ax2) = plt.subplots(1, 2, figsize = (30, 15))
ax1.imshow(test_image)
ax1.set_title('Original Image', fontsize=50)
ax2.imshow(dest)
ax2.set_title('Undistorted Image', fontsize=50)
Out[13]:
<matplotlib.text.Text at 0x1044c84a8>
In [14]:
# Test the calibrated camera on a road image
LANE_LINES_FOLDER_NAME = "test_images"
lane_line_image_paths = glob.glob(os.path.join(LANE_LINES_FOLDER_NAME, '*.jpg'))
lane_line_images = [mpimg.imread(lane_line_image_path) for lane_line_image_path in lane_line_image_paths]
In [15]:
f, (ax1, ax2) = plt.subplots(1, 2, figsize = (30, 15))
# Plot a sample image
sample_lane_image = lane_line_images[6]
ax1.set_title('Original Image', fontsize=50)
ax1.imshow(sample_lane_image)

# and undistort the image
dest = cv2.undistort(sample_lane_image, mtx, dist, None, mtx)
ax2.imshow(dest)
ax2.set_title('Undistorted Image', fontsize=50)
Out[15]:
<matplotlib.text.Text at 0x113cc7240>

Doing the perspective transform

In [16]:
# Define the size of the original image and the size of the image after
# the perspective transform

ORIGINAL_SIZE = 1280, 720
UNWARPED_SIZE = 1280, 720

def get_src_dst():    
    
    # images used to find the vanishing point
    straight_images = ["test_images/straight_lines1.jpg", "test_images/straight_lines2.jpg"]
    
    # define a triangle that represents the region of interest
    roi_points = np.array([[0, ORIGINAL_SIZE[1] - 50], \
                          [ORIGINAL_SIZE[0], ORIGINAL_SIZE[1] - 50], \
                          [ORIGINAL_SIZE[0]//2, ORIGINAL_SIZE[1]//2 + 50]], dtype = np.int32)
    
    # fill these points in
    roi = np.zeros((ORIGINAL_SIZE[1], ORIGINAL_SIZE[0]), dtype=np.uint8)
    cv2.fillPoly(roi, [roi_points], 1)

    # Define the matrix that are needed to calculate the vanishing point 
    Lhs = np.zeros((2,2), dtype = np.float32)
    Rhs = np.zeros((2,1), dtype = np.float32)

    # Find the straight lines in the image that correspond to the vanishing point
    for img_path in straight_images:
        img = mpimg.imread(img_path)
        img = cv2.undistort(img, mtx, dist)
        img_hls = cv2.cvtColor(img, cv2.COLOR_RGB2HLS)
        edges = cv2.Canny(img_hls[:, :, 1], 100, 200)
        lines = cv2.HoughLinesP(edges * roi, 0.5, np.pi/180, 20, None, 180, 120)
        for line in lines:
            for x1, y1, x2, y2 in line:
                normal = np.array([[-(y2-y1)], [x2-x1]], dtype = np.float32)
    #             print(normal)
    #             print(np.sqrt(np.sum(np.square(normal))))
                normal /= np.linalg.norm(normal)
    #             print(normal)
                point = np.array([[x1], [y1]], dtype = np.float32)
                outer = np.matmul(normal, normal.T)
    #             print(outer)
                Lhs += outer
                Rhs += np.matmul(outer, point)
                cv2.line(img, (x1, y1), (x2, y2), (255, 0, 0), thickness = 2)

    # calculate the vanishing point
    vanishing_point = np.matmul(np.linalg.inv(Lhs), Rhs)
#     print(vanishing_point)

    # Find the source and destination points
    top = vanishing_point[1] + 60
    bottom = ORIGINAL_SIZE[1] - 35
    width = 530

    def on_line(p1, p2, ycoord):
        return[p1[0] + (p2[0] - p1[0])/float(p2[1] - p1[1]) * (ycoord-p1[1]), ycoord]

    p1 = [vanishing_point[0] - width/2, top]
    p2 = [vanishing_point[0] + width/2, top]
    p3 = on_line(p2, vanishing_point, bottom)
    p4 = on_line(p1, vanishing_point, bottom)


    src = np.array([p1,p2,p3,p4], dtype=np.float32)

    dst = np.array([[0, 0], [UNWARPED_SIZE[0], 0],
                           [UNWARPED_SIZE[0], UNWARPED_SIZE[1]],
                           [0, UNWARPED_SIZE[1]]], dtype=np.float32)
    return(src, dst)
print(get_src_dst())
(array([[  374.52423096,   479.32043457],
       [  904.52423096,   479.32043457],
       [ 1812.94226074,   685.        ],
       [ -533.89379883,   685.        ]], dtype=float32), array([[    0.,     0.],
       [ 1280.,     0.],
       [ 1280.,   720.],
       [    0.,   720.]], dtype=float32))
In [17]:
# Helper function for the transform
def warper(image, src, dst):
    M = cv2.getPerspectiveTransform(src, dst)
    image_size = (image.shape[1], image.shape[0])
    warped = cv2.warpPerspective(image, M, image_size, flags=cv2.INTER_LINEAR) 
    return(warped)

# Plot the points where the perspective transform is to take place
def plot_perspective_transform_points(image):
    src, dst = get_src_dst()
    plt.imshow(image)
    plt.title("Points of the persepctive transform")
    plt.plot(src[0][0], src[0][1], 'o')
    plt.plot(src[1][0], src[1][1], 'o')
    plt.plot(src[2][0], src[2][1], 'o')
    plt.plot(src[3][0], src[3][1], 'o')
    plt.show()
In [18]:
# Plot the source points on the original image
plot_perspective_transform_points(dest)
In [19]:
# Plot the transformed image
src, dst = get_src_dst()
warped_lane_line_image = warper(dest, src, dst)
plt.title("Perspective transformed image")
plt.imshow(warped_lane_line_image)
Out[19]:
<matplotlib.image.AxesImage at 0x113c3a0f0>

Extracting the lane lines

Experiment with finding the most useful helpful channels

In [20]:
# Create an image wrapper class for easier conversion between color spaces
RGB_COLOR_SPACE = "RGB"
HLS_COLOR_SPACE = "HLS"
LAB_COLOR_SPACE = "LAB"
SINGLE_COLOR_CHANNEL = "Single"

from enum import Enum
class ColorSpace(Enum): 
    RGB = RGB_COLOR_SPACE
    HLS = HLS_COLOR_SPACE
    LAB = LAB_COLOR_SPACE 
    
class ImageWrapper:
    """
    This class is a wrapper class that allows for easier conversion between
    color spaces
    """
    def __init__(self, image, color_space):
        self.image = image
        self.width = image.shape[1]
        self.height = image.shape[0]
        self.color_space = color_space
        
    def _set_color_space(self, new_color_space):
        if self.color_space == new_color_space:
            pass
        else:
            if new_color_space == ColorSpace.RGB:
                if self.color_space == ColorSpace.HLS:
                    self.image = cv2.cvtColor(self.image, cv2.COLOR_HLS2RGB)
                elif self.color_space == ColorSpace.LAB:
                    self.image = cv2.cvtColor(self.image, cv2.COLOR_LAB2RGB)     
                self.color_space = new_color_space
                
            elif new_color_space == ColorSpace.HLS:
                if self.color_space == ColorSpace.RGB:
                    self.image = cv2.cvtColor(self.image, cv2.COLOR_RGB2HLS)
                elif self.color_space == ColorSpace.LAB:
                    self.image = cv2.cvtColor(self.image, cv2.COLOR_LAB2RGB)
                    self.image = cv2.cvtColor(self.image, cv2.COLOR_RGB2HLS)     
                self.color_space = new_color_space
                
            elif new_color_space == ColorSpace.LAB:
                if self.color_space == ColorSpace.RGB:
                    self.image = cv2.cvtColor(self.image, cv2.COLOR_RGB2LAB)
                elif self.color_space == ColorSpace.HLS:
                    self.image = cv2.cvtColor(self.image, cv2.COLOR_HLS2RGB)
                    self.image = cv2.cvtColor(self.image, cv2.COLOR_RGB2LAB)
                self.color_space = new_color_space
            
            
    def get_RGB(self):
        self._set_color_space(ColorSpace.RGB)
        return(self.image)
    def get_R(self):
        self._set_color_space(ColorSpace.RGB)
        return(self.image[:,:,0])
    def get_G(self):
        self._set_color_space(ColorSpace.RGB)
        return(self.image[:,:,1])
    def get_B(self):
        self._set_color_space(ColorSpace.RGB)
        return(self.image[:,:,2])
   
    def get_HLS(self):
        self._set_color_space(ColorSpace.HLS)
        return(self.image)
    def get_H(self):
        self._set_color_space(ColorSpace.HLS)
        return(self.image[:,:,0])
    def get_L(self):
        self._set_color_space(ColorSpace.HLS)
        return(self.image[:,:,1])
    def get_S(self):
        self._set_color_space(ColorSpace.HLS)
        return(self.image[:,:,2]) 
    
    def get_LAB(self):
        self._set_color_space(ColorSpace.LAB)
        return(self.image)
    def get_l(self):
        self._set_color_space(ColorSpace.LAB)
        return(self.image[:,:,0])
    def get_a(self):
        self._set_color_space(ColorSpace.LAB)
        return(self.image[:,:,1])
    def get_b(self):
        self._set_color_space(ColorSpace.LAB)
        return(self.image[:,:,2]) 
    
    def get_gray(self):
        return(sel)
In [21]:
from matplotlib.colors import hsv_to_rgb

def plot_all_color_channels(image):
    """
    The function simply plots all the different kinds of color channels so that 
    it is easier to visual which color channels are more useful
    """
    f, ((ax1, ax2, ax3), (ax4, ax5, ax6), (ax7, ax8, ax9), (ax10, ax11, ax12)) = plt.subplots(4, 3, figsize = (30, 15))
    f.tight_layout()
    wspace = 0.25   # the amount of width reserved for blank space between subplots
    hspace = 0.25   # the amount of height reserved for white space between subplots
    f.subplots_adjust(wspace = wspace, hspace = hspace)
    font = {'size' : 30}
    ax1.imshow(image.get_R(), cmap = 'gray')
    ax1.set_title("R", fontdict=font)
    ax2.imshow(image.get_G(), cmap = 'gray')
    ax2.set_title("G", fontdict=font)
    ax3.imshow(image.get_B(), cmap = 'gray')
    ax3.set_title("B", fontdict = font)
    ax4.imshow(image.get_H(), cmap = 'gray')
    ax4.set_title("H", fontdict = font)
    ax5.imshow(image.get_L(), cmap = 'gray')
    ax5.set_title("L", fontdict = font)
    ax6.imshow(image.get_S(), cmap = 'gray')
    ax6.set_title("S", fontdict = font)
    
    ax7.imshow(image.get_l(), cmap = 'gray')
    ax7.set_title("L", fontdict = font)
    ax8.imshow(image.get_a(), cmap = 'gray')
    ax8.set_title("A", fontdict = font)
    ax9.imshow(image.get_b(), cmap = 'gray')
    ax9.set_title("B", fontdict = font)
    
    ax10.imshow(image.get_RGB())
    ax10.set_title("RGB", fontdict = font)
    ax11.imshow(hsv_to_rgb(image.get_HLS()))
    ax11.set_title("HLS", fontdict = font)
    ax12.imshow(image.get_LAB())
    ax12.set_title("LAB", fontdict = font)
In [22]:
# First undistort the lane image
lane_line_images = [cv2.undistort(image, mtx, dist, None, mtx) for image in lane_line_images]
                    
# Now wrap them in the custom class created above
wrapped_lane_line_images = [ImageWrapper(image, ColorSpace.RGB) for image in lane_line_images]
In [23]:
# Plot the images
sample_image = wrapped_lane_line_images[6]
plot_all_color_channels(sample_image)

It seems like the most useful channel are the S, and B channels to detect yellow lane lines which are in the shadow.

The HLS's L and R, G channels all do a good job at detect the white lane lines, even in the shadows

Experiment with various methods to find lane lines

In [24]:
# Define the red channel for the sample image
sample_image_R = sample_image.get_R()
In [25]:
# Define some generic helper functions and constants
UINT_8_MAX = 255

def scale_image(image, max_val):
    return((image/np.max(image) * max_val))

def binary_mask(image, threshold):
    """
    Takes in an image, and scales it to 0-255, then creates a binary image 
    where the active pixels are set according to the threshold
    
    :::params image: a (length x width) array (only 1 color channel)
              threshold: the numbers which determine the active pixels
    """
    # Get the absolute value of the pixels
    image = np.abs(image)

    # Scale to 0-255
    image = scale_image(image, UINT_8_MAX)
    binary_output = np.zeros_like(image)
    binary_output[(image >= threshold[0]) & (image <= threshold[1])] = 1
    return(binary_output.astype(np.uint8))

# Define a sobel helper function
def sobel_calc(image, kernel_size):
    """
    This function takes an image of a single color channel, and returns a 2-tuple of images
    with the first element of the tuple being the Sobel operator on the x axis, and the second
    element being the Sobel operator on the y axis
    """
    sobel_x = cv2.Sobel(image, cv2.CV_64F, 1, 0, ksize = kernel_size) 
    sobel_y = cv2.Sobel(image, cv2.CV_64F, 0, 1, ksize = kernel_size)
    return((sobel_x), (sobel_y))
In [26]:
def axis_threshold(image, axis, sobel_kernel, sobel_threshold):
    """
    Takes in an image and returns a binary image dependent on the mag_threshold
    :::params image: a (length x width) array (only 1 color channel)
              axis: the direction to apply the sobel operator, 0 is x, 1 is y
              sobel_kernel: the size of the sobel kernel
              sobel_threshold: the max and min sobel values which determines which pixels are active
    """
    image_sobel = sobel_calc(image, sobel_kernel)
    sobel_x = image_sobel[0]
    sobel_y = image_sobel[1]
    if (axis == 0):
        binary_output = binary_mask(sobel_x, sobel_threshold)
    else:
        binary_output = binary_mask(sobel_y, sobel_threshold)
    
    return(binary_output)
In [27]:
# Example use:
axis_sobel_kernel_size = 3
ax_threshold = (30, 255)
sobel_x_R = axis_threshold(sample_image_R, 0, axis_sobel_kernel_size, ax_threshold)
sobel_y_R = axis_threshold(sample_image_R, 1, axis_sobel_kernel_size, ax_threshold)
In [28]:
# Plot the result
f, (ax1, ax2) = plt.subplots(1, 2)
ax1.imshow(sobel_x_R, cmap = 'gray')
ax2.imshow(sobel_y_R, cmap = 'gray')
Out[28]:
<matplotlib.image.AxesImage at 0x11d063160>
In [29]:
def magnitude_threshold(image, sobel_kernel, mag_threshold):
    """
    Takes in an image and returns a binary image dependent on the mag_threshold
    :::params image: a (length x width) array (only 1 color channel)
              sobel_kernel: the size of the sobel kernel
              mag_threshold: the max and min magnitudes which determines which pixels are active
    """
    # Get the x, y sobels
    image_sobel = sobel_calc(image, sobel_kernel)
    sobel_x = image_sobel[0]
    sobel_y = image_sobel[1]
    
    # Find the magnitude 
    mag = np.sqrt(np.square(sobel_x) + np.square(sobel_y))
    
    # Get a binary mask of the magnitude
    binary_output = binary_mask(mag, mag_threshold)
    
    return(binary_output)
In [30]:
mag_threshold = (30, 255)
mag_sobel_kernel_size = 3
mag_R = magnitude_threshold(sample_image_R, mag_sobel_kernel_size, mag_threshold)
plt.imshow(mag_R, cmap = 'gray')
Out[30]:
<matplotlib.image.AxesImage at 0x12f444668>
In [31]:
def angle_threshold(image, sobel_kernel, angle_threshold):
    """
    Takes in an image and returns a binary image dependent on the mag_threshold
    :::params image: a (length x width) array (only 1 color channel)
              sobel_kernel: the size of the sobel kernel
              angle_threshold: the max and min angles which determines which pixels are active
    """
    # Apply sobel operator on the image
    image_sobel = sobel_calc(image, sobel_kernel)
    sobel_x = image_sobel[0]
    sobel_y = image_sobel[1]
    
    # 3) Take the absolute value of the x and y gradients
    abs_sobel_x = np.absolute(sobel_x)
    abs_sobel_y = np.absolute(sobel_y)
    
    
    # 4) Use np.arctan2(abs_sobely, abs_sobelx) to calculate the direction of the gradient 
    angle = np.arctan2(abs_sobel_y, abs_sobel_x)
    
    # 5) Create a binary mask where direction thresholds are met
    binary_output = np.zeros_like(angle)
    binary_output[(angle >= angle_threshold[0]) & (angle <= angle_threshold[1])] = 1
    return(binary_output.astype(np.uint8))
In [32]:
# Test it
ang_threshold = (0.7, 1.3)# here pi/2 = 90 degrees so 90 degrees ~= 1.7
ang_sobel_kernel_size = 11
angle_R = angle_threshold(sample_image_R, ang_sobel_kernel_size, ang_threshold)
In [33]:
plt.imshow(angle_R, cmap = 'gray')
Out[33]:
<matplotlib.image.AxesImage at 0x12f4ad0b8>

Using these threshold functions plot the results of the:

  • 1) S,and B channels to detect yellow lane lines which are in the shadow.
  • 2) HLS's L and R, G channels all do a good job at detect the white lane lines, even in the shadows
In [34]:
# Helper function to get the useful color channels 
def get_color_channels(image):
    R = image.get_R()
    G = image.get_G()
    S = image.get_S()
    l = image.get_l()
    b = image.get_b()
    return([R, G, S, l, b])

import matplotlib.gridspec as gridspec

def plot_thresholds(images, tophat = False):
    """
    This function plots the data using the output of get_data_in_bin
    
    params data: this is a list of data frame rows, one from each bin
    
    """
    
    # Define spacing between the plots
    fig = plt.figure(figsize=(30, 15))
    gs = gridspec.GridSpec(1,5)
    color_channels = ["R", "G", "S", "l", "b"]
   
    # loop through the 
    for i in range(len(images)):
        ax = fig.add_subplot(gs[i])
        
        # If we have a row from the data frame, then we need to extract 
        # the raw data 
        if not tophat:
            ax.imshow(images[i], cmap = 'gray')
        else:
            ax.imshow(images[i])
        ax.set_title(color_channels[i], fontdict = {'size' :30})
    gs.tight_layout(fig)
    plt.show()
In [35]:
# Define the thresholds to be used`
sobel_threshold = (20, 255)
mag_threshold = (20, 255)
ang_threshold = (0.7, 1.2)

# Set the kernel sizes
axis_s_size = 5
angle_s_size = 5
mag_s_size = 5
In [36]:
# Use all the thresholding techniques above on all the color channels
all_channels = get_color_channels(sample_image)
axis_x_thresholded_images = [axis_threshold(image, 0, sobel_kernel = axis_s_size, \
                                            sobel_threshold = sobel_threshold) for image in all_channels]
axis_y_thresholded_images = [axis_threshold(image, 1, sobel_kernel = axis_s_size, \
                                            sobel_threshold = sobel_threshold) for image in all_channels]
magnitude_thresholded_images = [magnitude_threshold(image, sobel_kernel = mag_s_size, \
                                                    mag_threshold = mag_threshold) for image in all_channels]
angle_thresholded_images = [angle_threshold(image, sobel_kernel = angle_s_size, \
                                            angle_threshold = ang_threshold) for image in all_channels]
In [37]:
plot_thresholds(all_channels)
In [38]:
plot_thresholds(axis_x_thresholded_images)
In [39]:
plot_thresholds(axis_y_thresholded_images)
In [40]:
plot_thresholds(magnitude_thresholded_images)
In [41]:
plot_thresholds(angle_thresholded_images)
In [42]:
useful_images = [axis_x_thresholded_images[0], \
                 axis_x_thresholded_images[1], \
                 axis_x_thresholded_images[3], \
                 axis_x_thresholded_images[4], \
                 axis_y_thresholded_images[4],\
                 magnitude_thresholded_images[4]] 
In [43]:
stacked = np.zeros_like(useful_images[0])
for image in useful_images:
    stacked[(image == 1)] += 1
In [44]:
plt.imshow(stacked, cmap = 'gray')
plt.title("Stacked image", fontsize = 30)
Out[44]:
<matplotlib.text.Text at 0x11923f390>
In [45]:
non_tophat_binary_image = np.zeros_like(stacked)
non_tophat_binary_image[stacked >= (len(useful_images)/2)] = 1
plt.imshow(non_tophat_binary_image, cmap = 'gray')
plt.title("Thresholded stacked image")
Out[45]:
<matplotlib.text.Text at 0x121e94f98>
  • Seems like the LAB's b channel and HLS's s channel are pretty good for detecting the yellow lane lines.
  • The HLS's s channel also seems to do a good job in detecting the white lane lines on a grey surface

Use a tophat and erode and see if it makes the lane lines clearer

In [46]:
# Define the morphological transforms
def erode(image, kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))):
    return(cv2.morphologyEx(image, cv2.MORPH_ERODE, kernel))

def tophat(image, kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))):
    return(cv2.morphologyEx(image, cv2.MORPH_TOPHAT, kernel))

def close(image, kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))):
    return(cv2.morphologyEx(image, cv2.MORPH_CLOSE, kernel))

def median_filter(image, filter_size):
    return(cv2.medianBlur(image, filter_size))

def adaptive_transform(image, blocksize, C):
    return(cv2.adaptiveThreshold(image, 1, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, \
                         cv2.THRESH_BINARY, blocksize, C))
In [47]:
# Seems a bit noist on the edge 
close_kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9,9))
non_tophat_binary_image = close(non_tophat_binary_image, close_kernel)
In [48]:
plt.imshow(non_tophat_binary_image, cmap = 'gray')
Out[48]:
<matplotlib.image.AxesImage at 0x11b151860>
In [49]:
non_tophat_binary_image = erode(non_tophat_binary_image)
In [50]:
plt.imshow(non_tophat_binary_image, cmap = 'gray')
Out[50]:
<matplotlib.image.AxesImage at 0x11b0ad8d0>
In [51]:
def get_non_tophat_binary_image(wrapped_image):
    
    # Define the thresholds to be used
    sobel_threshold = (20, 255)
    mag_threshold = (20, 255)
    ang_threshold = (0.7, 1.2)

    # Set the kernel sizes
    axis_s_size = 5
    angle_s_size = 5
    mag_s_size = 5
    smoothing_k_size = 5
        
    # Do the thresholding for the images
    all_channels = get_color_channels(wrapped_image)
    axis_x_thresholded_images = [axis_threshold(image, 0, sobel_kernel = axis_s_size, \
                                                sobel_threshold = sobel_threshold) for image in all_channels]
    axis_y_thresholded_images = [axis_threshold(image, 1, sobel_kernel = axis_s_size, \
                                                sobel_threshold = sobel_threshold) for image in all_channels]
    magnitude_thresholded_images = [magnitude_threshold(image, sobel_kernel = mag_s_size, \
                                                        mag_threshold = mag_threshold) for image in all_channels]
    angle_thresholded_images = [angle_threshold(image, sobel_kernel = angle_s_size, \
                                                angle_threshold = ang_threshold) for image in all_channels]
    
    
    # select the useful images
    useful_images = [axis_x_thresholded_images[0], \
                 axis_x_thresholded_images[1], \
                 axis_x_thresholded_images[3], \
                 axis_x_thresholded_images[4], \
                 axis_y_thresholded_images[4],\
                 magnitude_thresholded_images[4]] 

    
    stacked = np.zeros_like(useful_images[0])
#     plt.imshow(stacked, cmap = 'gray')
    
    for image in useful_images:
        stacked[(image == 1)] += 1
        
    non_tophat_binary_image = np.zeros_like(stacked)
    non_tophat_binary_image[stacked >= (len(useful_images)/2)] = 1
    
    close_kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9, 9))
    non_tophat_binary_image = erode(close(non_tophat_binary_image, close_kernel))

    return(non_tophat_binary_image.astype(np.uint8))  
In [52]:
non_tophat_binary_image = get_non_tophat_binary_image(sample_image)
plt.imshow(non_tophat_binary_image, cmap = 'gray')
Out[52]:
<matplotlib.image.AxesImage at 0x11b06cb38>

Try using the tophat transform

In [53]:
# Tophat transform all the images
tophat_kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
all_channels_tophat = [tophat(image, tophat_kernel) for image in all_channels]
axis_x_thresholded_images = [axis_threshold(image, 0, sobel_kernel = axis_s_size, sobel_threshold = sobel_threshold) for image in all_channels_tophat]
axis_y_thresholded_images = [axis_threshold(image, 1, sobel_kernel = axis_s_size, sobel_threshold = sobel_threshold) for image in all_channels_tophat]
magnitude_thresholded_images = [magnitude_threshold(image, sobel_kernel = mag_s_size, mag_threshold = mag_threshold) for image in all_channels_tophat]
angle_thresholded_images = [angle_threshold(image, sobel_kernel = angle_s_size, angle_threshold = ang_threshold) for image in all_channels_tophat]
In [54]:
plot_thresholds(all_channels_tophat, tophat = True)
In [55]:
plot_thresholds(axis_x_thresholded_images)
In [56]:
plot_thresholds(axis_y_thresholded_images)
In [57]:
plot_thresholds(magnitude_thresholded_images)
In [58]:
plot_thresholds(angle_thresholded_images)
  • Use HLS's L channel, and the LAB's L and B channel to try to find the lane lines
  • But first try to get rid of the horizontal noise by using the axis_threshold function
In [59]:
def stacked_tophat(wrapped_image, kernel):
    L_channel = wrapped_image.get_L()
    l_channel = wrapped_image.get_l() 
    b_channel = wrapped_image.get_b()
#     plt.imshow(tophat(b_channel, kernel))
#     ang_threshold = (0.7, 1.2)
#     angle_sobel_size = 5
#     median_filter_size = 11
#     angle_thresholded_b_channel = median_filter(angle_threshold(b_channel, angle_sobel_size, \
#                                                   ang_threshold), median_filter_size)
    tophat_L = scale_image(tophat(L_channel, kernel), 255)
    tophat_l = scale_image(tophat(l_channel, kernel), 255)
    tophat_b = scale_image(tophat(b_channel, kernel), 255)
# #     angle_thresholded_b_channel = scale_image(angle_thresholded_b_channel, 255)
#     # Note here that we add tophat_b twice as only the b channel detects the yellow lane lines
    stacked_tophat = scale_image(tophat_L + tophat_l + \
                                 tophat_b, \
                                 255).astype(np.uint8)
    return(stacked_tophat)
# stacked_tophat_kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (19, 19))
# stacked_tophat(sample_image, stacked_tophat_kernel)
In [60]:
# First stack the tophat images
stacked_tophat_kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (13, 13))
stacked_tophat_image = stacked_tophat(sample_image, stacked_tophat_kernel)

# Remove the x noise
sobel_kernel = 5
sobel_threshold = (10, 80)
stacked_tophat_image_x_removed = axis_threshold(stacked_tophat_image, 0, sobel_kernel, sobel_threshold)

# Remove the salt and pepper noise
filter_size = 5
stacked_tophat_image_x_sp_removed = median_filter(stacked_tophat_image_x_removed, filter_size)

# Morphological close
close_kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9, 9))
close_stacked_tophat_image_x_sp_removed = close(stacked_tophat_image_x_sp_removed, close_kernel)

# Plot the images in each stage
f, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize = (30, 15))
ax1.imshow(stacked_tophat_image, cmap = 'gray')
ax2.imshow(stacked_tophat_image_x_removed)
ax3.imshow(stacked_tophat_image_x_sp_removed)
ax4.imshow(close_stacked_tophat_image_x_sp_removed)
# plt.imshow(close(axis_threshold(stacked_tophat_image, 0, sobel_kernel, sobel_threshold), close_kernel))
# adapt_stacked_tophat_image = cv2.adaptiveThreshold(stacked_tophat_image, 1, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 13, -9) 
# plt.imshow(adapt_stacked_tophat_image)
Out[60]:
<matplotlib.image.AxesImage at 0x11a4ca908>
In [61]:
def get_tophat_binary_image(wrapped_image):
    stacked_tophat_kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (13, 13))
    stacked_tophat_image = stacked_tophat(wrapped_image, stacked_tophat_kernel)

    # Remove the x noise
    sobel_kernel = 5
    sobel_threshold = (10, 80)
    stacked_tophat_image_x_removed = axis_threshold(stacked_tophat_image, 0, sobel_kernel, sobel_threshold)

    # Remove the salt and pepper noise
    filter_size = 5
    stacked_tophat_image_x_sp_removed = median_filter(stacked_tophat_image_x_removed, filter_size)

    # Morphological close
    close_kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9, 9))
    close_stacked_tophat_image_x_sp_removed = close(stacked_tophat_image_x_sp_removed, close_kernel)
    return(close_stacked_tophat_image_x_sp_removed)
In [62]:
tophat_binary_image = get_tophat_binary_image(sample_image)
plt.imshow(tophat_binary_image, cmap = 'gray')
Out[62]:
<matplotlib.image.AxesImage at 0x11b0a80f0>
In [63]:
# First do the persective transform
non_tophat_binary_warped = warper(non_tophat_binary_image, src, dst)
tophat_binary_warped = warper(tophat_binary_image, src, dst)
f, (ax1, ax2) = plt.subplots(1, 2, figsize = (30, 15))
ax1.imshow(non_tophat_binary_warped, cmap = 'gray')
ax2.imshow(tophat_binary_warped, cmap = 'gray')
Out[63]:
<matplotlib.image.AxesImage at 0x11951f978>

Take a look at the two kinds of transforms for all the images

In [64]:
non_tophat_binary_warped_images = [warper(get_non_tophat_binary_image(image), src, dst) \
                                   for image in wrapped_lane_line_images]
tophat_binary_warped_images = [warper(get_tophat_binary_image(image), src, dst) \
                        for image in wrapped_lane_line_images]
original_images = [cv2.cvtColor(image.get_RGB(),cv2.COLOR_RGB2GRAY) for image in wrapped_lane_line_images]
In [65]:
fig = plt.figure(figsize = (30, 15))
gs = gridspec.GridSpec(8, 3)
for i, images in enumerate(zip(non_tophat_binary_warped_images,\
                  tophat_binary_warped_images,\
                  original_images)):
    for j, image in enumerate(images):
        ax = fig.add_subplot(gs[i,j])
        ax.imshow(image, cmap = 'gray')
gs.tight_layout(fig)
plt.show()
In [66]:
# Seems like the non_tophat_binary_warped_images looks better
binary_warped = warper(get_non_tophat_binary_image(sample_image), src, dst)
plt.title("Binary warped image")
plt.imshow(binary_warped, cmap = 'gray')
Out[66]:
<matplotlib.image.AxesImage at 0x119335390>

Finding the lane lines

In [67]:
# Get the histogram of the pixel values for the bottom half of the image
hist = np.sum(binary_warped[binary_warped.shape[0]/2:,:], axis = 0)
plt.plot(hist)
/Users/kevinlu/miniconda3/envs/carnd-term1/lib/python3.5/site-packages/ipykernel/__main__.py:2: VisibleDeprecationWarning: using a non-integer number instead of an integer will result in an error in the future
  from ipykernel import kernelapp as app
Out[67]:
[<matplotlib.lines.Line2D at 0x129814be0>]
In [68]:
# Convert the image to RGB
out_image = (np.dstack((binary_warped, binary_warped, binary_warped)) * 255).astype(np.uint8)
print(out_image.shape)
print(out_image[0:1])
plt.imshow(out_image)
(720, 1280, 3)
[[[0 0 0]
  [0 0 0]
  [0 0 0]
  ..., 
  [0 0 0]
  [0 0 0]
  [0 0 0]]]
Out[68]:
<matplotlib.image.AxesImage at 0x12987bf98>
In [69]:
# Find the base of the lines
midpoint = np.int(UNWARPED_SIZE[0]/2)
base_left_x = np.argmax(hist[:midpoint])
base_right_x = np.argmax(hist[midpoint:]) + midpoint
print("Base of left lane is: {0}\nBase of right lane is: {1}"\
      .format(base_left_x, base_right_x))
Base of left lane is: 404
Base of right lane is: 888
In [70]:
# Get the height for the sliding window
n_windows = 9
window_height = np.int(binary_warped.shape[0]/n_windows)
In [71]:
# Identify the x and y positions of all non-zero pixels in the image
# These values are stored in nonzeroy and nonzerox, so the first element of nonzerox, and nonzeroy would give the 
# first coordinate that has a nonzero
nonzero = binary_warped.nonzero()
nonzeroy = np.array(nonzero[0])
nonzerox = np.array(nonzero[1])
In [72]:
# Current positions
current_left_x = base_left_x
current_right_x = base_right_x

# Set the width of the windows
width = 50

# Set the minimum number of pixels found to recenter the window
minpix = 50

# Create empty lists to receive the left and right lane pixel indcies
left_lane_idx = []
right_lane_idx = []
In [73]:
# Step through the windows one by one
for window in range(n_windows):
    # Height for the windows
    win_y_low = binary_warped.shape[0] - (window + 1) * window_height
    win_y_high = binary_warped.shape[0] - window * window_height
    
    # starting and ending x coordinates of the window for the left lane line
    win_x_left_low = current_left_x - width
    win_x_left_high = current_left_x + width
    
    # starting and ending x coordinates of the window for the right lane line
    win_x_right_low = current_right_x - width
    win_x_right_high = current_right_x + width
    
    # Draw green rectangles on the RGB transformed image
    cv2.rectangle(out_image, (win_x_left_low, win_y_low), (win_x_left_high, win_y_high), (0, 255, 0), 2)
    cv2.rectangle(out_image,(win_x_right_low,win_y_low),(win_x_right_high,win_y_high),(0,255,0), 2) 

    # Identify the indexes of nonzero pixels in the nonzerox, and nonzeroy arrays
    # note that the index will have all the combinations of x, and y coordinates that are non-zero
    # within our specified window
    good_left_idx = ((nonzeroy >= win_y_low) & (nonzeroy < win_y_high) & \
                     (nonzerox >= win_x_left_low) & (nonzerox < win_x_left_high)).nonzero()[0]
    good_right_idx = ((nonzeroy >= win_y_low) & (nonzeroy < win_y_high) & \
                      (nonzerox >= win_x_right_low) & (nonzerox < win_x_right_high)).nonzero()[0]
    
#     print(good_left_idx)
#     print(good_right_idx)
    
    # Append these indices to the lists
    left_lane_idx.append(good_left_idx)
    right_lane_idx.append(good_right_idx)
    
    if len(good_left_idx) > minpix:
        current_left_x = np.int(np.mean(nonzerox[good_left_idx]))
    if len(good_right_idx) > minpix:
        current_right_x = np.int(np.mean(nonzerox[good_right_idx]))
In [74]:
# Concatenate the arrays of indices which represent the nonzero elements int he 

left_lane_idx = np.concatenate(left_lane_idx)
right_lane_idx = np.concatenate(right_lane_idx)

# Extract left and right line pixel positions
left_x = nonzerox[left_lane_idx]
left_y = nonzeroy[left_lane_idx] 
right_x = nonzerox[right_lane_idx]
right_y = nonzeroy[right_lane_idx] 
In [75]:
plt.imshow(out_image)
Out[75]:
<matplotlib.image.AxesImage at 0x12ac24198>
In [76]:
# Convert from pixel space to meters
Y_M_PER_PIXEL = 30/720 # 720 is the height of the image
X_M_PER_PIXEL = 3.7/700 # 700 is the width of the lane in pixel 

def find_poly_fit_with_window(binary_warped):
    # Get the histogram of the pixel values for the bottom half of the image
    hist = np.sum(binary_warped[binary_warped.shape[0]/2:,:], axis = 0)
    
    # Turn the binary image into RGB
    out_image = (np.dstack((binary_warped, binary_warped, binary_warped)) * 255).astype(np.uint8)
    
    # Find the base of the lines
    midpoint = np.int(UNWARPED_SIZE[0]/2)
    base_left_x = np.argmax(hist[:midpoint])
    base_right_x = np.argmax(hist[midpoint:]) + midpoint

    # Get the height for the sliding window
    n_windows = 9
    window_height = np.int(binary_warped.shape[0]/n_windows)

    # The some_array.nonzero() functions return d lists where d is the number of dimensions in the some_array
    # Use this to identify the x and y positions of all non-zero pixels in the image
    
    # These values are stored in nonzeroy and nonzerox, so the first element of nonzerox, and nonzeroy would give the 
    # first coordinate that has a nonzero pixel i.e.the pixel is not black
    nonzero = binary_warped.nonzero() # returns 2 lists of the same length, each list contains the indexes of nonzero elements
    nonzeroy = np.array(nonzero[0])
    nonzerox = np.array(nonzero[1])
    

    # Current positions
    current_left_x = base_left_x
    current_right_x = base_right_x

    # Set the width of the windows
    width = 100

    # Set the minimum number of pixels found to recenter the window
    minpix = 50

    # Create empty lists to receive the left and right lane pixel indcies
    left_lane_idx = []
    right_lane_idx = []

    # Step through the windows one by one
    for window in range(n_windows):
        # Height for the windows
        win_y_low = binary_warped.shape[0] - (window + 1) * window_height
        win_y_high = binary_warped.shape[0] - window * window_height

        # starting and ending x coordinates of the window for the left lane line
        win_x_left_low = current_left_x - width
        win_x_left_high = current_left_x + width

        # starting and ending x coordinates of the window for the right lane line
        win_x_right_low = current_right_x - width
        win_x_right_high = current_right_x + width

        # Draw green rectangles on the RGB transformed image
        cv2.rectangle(out_image, (win_x_left_low, win_y_low), (win_x_left_high, win_y_high), (0, 255, 0), 2)
        cv2.rectangle(out_image, (win_x_right_low, win_y_low), (win_x_right_high, win_y_high), (0, 255, 0), 2) 

        # Identify the indexes of nonzero pixels in the nonzerox, and nonzeroy arrays
        # note that the index will all the combinations of x, and y coordinates that are non-zero
        
        # As some_array >= some_condition returns a boolean array we can & these arrays together, and
        # find the indexes of the nonzeroy, and nonzerox arrays that satisfy these conditions, noting
        # that the nonzery and nonzerox arrays themselves are the actual coordinates of the pixels that
        # aren't 0. Hence, we are able to find the coordinates in the original image that aren't black and 
        # also in our specfied window

        good_left_idx = ((nonzeroy >= win_y_low) & (nonzeroy < win_y_high) & \
                         (nonzerox >= win_x_left_low) & (nonzerox < win_x_left_high)).nonzero()[0]
        good_right_idx = ((nonzeroy >= win_y_low) & (nonzeroy < win_y_high) & \
                          (nonzerox >= win_x_right_low) & (nonzerox < win_x_right_high)).nonzero()[0]
        
        # Append all the indexes that are non-zero within the window into an array
        # so that they can be used for coloring later
        left_lane_idx.append(good_left_idx)
        right_lane_idx.append(good_right_idx)
        
        # If there are enough pixels in this window, then move the window to the middle of those pixels
        if len(good_left_idx) > minpix:
            current_left_x = np.int(np.mean(nonzerox[good_left_idx]))
        if len(good_right_idx) > minpix:
            current_right_x = np.int(np.mean(nonzerox[good_right_idx]))
            
    # Concatenate the arrays of indices, as it is a list of lists due to 
    # appending good_left_idx/good_right_idx to the array
    left_lane_idx = np.concatenate(left_lane_idx)
    right_lane_idx = np.concatenate(right_lane_idx)

    # Extract left and right line pixel positions
    left_x = nonzerox[left_lane_idx]
    left_y = nonzeroy[left_lane_idx] 
    right_x = nonzerox[right_lane_idx]
    right_y = nonzeroy[right_lane_idx] 
    
    # Fit a second order polynomial to each
    left_fit = np.polyfit(left_y, left_x, 2)
    right_fit = np.polyfit(right_y, right_x, 2)
    
    # Extract left and right line pixel positions
    left_x_m = nonzerox[left_lane_idx] * X_M_PER_PIXEL
    left_y_m = nonzeroy[left_lane_idx] * Y_M_PER_PIXEL
    right_x_m = nonzerox[right_lane_idx] * X_M_PER_PIXEL
    right_y_m = nonzeroy[right_lane_idx] * Y_M_PER_PIXEL 

    # Fit a second order polynomial to each
    left_fit_m = np.polyfit(left_y_m, left_x_m, 2)
    right_fit_m = np.polyfit(right_y_m, right_x_m, 2)
    
    return(left_fit, right_fit, left_fit_m, right_fit_m, left_lane_idx, right_lane_idx)
In [77]:
# Test our function
left_fit, right_fit, left_fit_m, right_fit_m, left_lane_idx, right_lane_idx = find_poly_fit_with_window(binary_warped) 
plt.imshow(binary_warped, cmap = 'gray')
/Users/kevinlu/miniconda3/envs/carnd-term1/lib/python3.5/site-packages/ipykernel/__main__.py:7: VisibleDeprecationWarning: using a non-integer number instead of an integer will result in an error in the future
Out[77]:
<matplotlib.image.AxesImage at 0x12ac8fc50>
In [78]:
def find_poly_fit_after_initial_window(binary_warped, left_fit, right_fit):
    """
    Takes a binary warped that is perspective transformed which the polynomial
    fitted lane lines and outputs the new coefficients for the left and right lane lines
    
    :::params binary_warped: a perspective transformed binary image 
    
              left_fit: the coefficients of the polynomial fit for the left lane line
              
              right_fit: the coefficients of the polynomial fit for the right lane line
    """
    # Get the coordinates of the non-zero pixels
    nonzero = binary_warped.nonzero()
    nonzeroy = np.array(nonzero[0])
    nonzerox = np.array(nonzero[1])
    margin = 100
    
    # Get the left and right lane indexes
    left_lane_idx = ((nonzerox > (left_fit[0]*(nonzeroy**2) + \
                                   left_fit[1]*nonzeroy + left_fit[2] - margin))
                      & (nonzerox < (left_fit[0]*(nonzeroy**2) + \
                                     left_fit[1]*nonzeroy + left_fit[2] + margin))) 
    right_lane_idx = ((nonzerox > (right_fit[0]*(nonzeroy**2) + \
                                    right_fit[1]*nonzeroy + right_fit[2] - margin)) &
                       (nonzerox < (right_fit[0]*(nonzeroy**2) + \
                                    right_fit[1]*nonzeroy + right_fit[2] + margin)))  
    
    # Extract left and right line pixel positions
    left_x = nonzerox[left_lane_idx]
    left_y = nonzeroy[left_lane_idx] 
    right_x = nonzerox[right_lane_idx]
    right_y = nonzeroy[right_lane_idx] 
    
    # Fit a second order polynomial to each
    left_fit = np.polyfit(left_y, left_x, 2)
    right_fit = np.polyfit(right_y, right_x, 2)
    
    # Extract left and right line pixel positions
    left_x_m = nonzerox[left_lane_idx] * X_M_PER_PIXEL
    left_y_m = nonzeroy[left_lane_idx] * Y_M_PER_PIXEL
    right_x_m = nonzerox[right_lane_idx] * X_M_PER_PIXEL
    right_y_m = nonzeroy[right_lane_idx] * Y_M_PER_PIXEL 

    # Fit a second order polynomial to each
    left_fit_m = np.polyfit(left_y_m, left_x_m, 2)
    right_fit_m = np.polyfit(right_y_m, right_x_m, 2)
    
    return(left_fit, right_fit, left_fit_m, right_fit_m, left_lane_idx, right_lane_idx)

Plotting the lane lines

In [79]:
# Fit a second order polynomial to each
left_fit = np.polyfit(left_y, left_x, 2)
right_fit = np.polyfit(right_y, right_x, 2)

# Visualize the results
plot_y = np.linspace(0, binary_warped.shape[0]-1, binary_warped.shape[0])
left_fit_x = left_fit[0] * plot_y ** 2 + left_fit[1] * plot_y + left_fit[2]
right_fit_x = right_fit[0] * plot_y ** 2 + right_fit[1] * plot_y + right_fit[2]

# Color the left and right lane lines
out_image[nonzeroy[left_lane_idx], nonzerox[left_lane_idx]] = [255, 0, 0]
out_image[nonzeroy[right_lane_idx], nonzerox[right_lane_idx]] = [0, 0 ,255]

# Plot the image with the lane lines
plt.imshow(out_image)
plt.plot(left_fit_x, plot_y, color='yellow')
plt.plot(right_fit_x, plot_y, color='yellow')
plt.xlim(0, 1280)
plt.ylim(720, 0)
Out[79]:
(720, 0)
In [80]:
def get_fitted_lines(binary_warped, left_fit, right_fit):
    
    # Get data needed for visualization
    plot_y = np.linspace(0, binary_warped.shape[0]-1, binary_warped.shape[0])
    left_fit_x = left_fit[0] * plot_y ** 2 + left_fit[1] * plot_y + left_fit[2]
    right_fit_x = right_fit[0] * plot_y ** 2 + right_fit[1] * plot_y + right_fit[2]
    return(plot_y, left_fit_x, right_fit_x)
    
 
def plot_fitted_lane_lines(binary_warped, plot_y, left_fit_x, right_fit_x, left_lane_idx, right_lane_idx):
    
    # Get the fitted coordinates
    plot_y, left_fit_x, right_fit_x = get_fitted_lines(binary_warped, left_fit, right_fit)
    
    # Create the RGB image
    out_image = (np.dstack((binary_warped, binary_warped, binary_warped)) * 255).astype(np.uint8)
    nonzero = binary_warped.nonzero()
    nonzeroy = np.array(nonzero[0])
    nonzerox = np.array(nonzero[1])
    
    # Color the left and right lane lines
    out_image[nonzeroy[left_lane_idx], nonzerox[left_lane_idx]] = [255, 0, 0]
    out_image[nonzeroy[right_lane_idx], nonzerox[right_lane_idx]] = [0, 0 ,255]

    # Plot the image with the lane lines
    plt.imshow(out_image)
    plt.title("Binary warped fitted lines")
    plt.plot(left_fit_x, plot_y, color='yellow')
    plt.plot(right_fit_x, plot_y, color='yellow')
    plt.xlim(0, 1280)
    plt.ylim(720, 0)
In [81]:
# Test our function for plotting
plot_y, left_fit_x, right_fit_x = get_fitted_lines(binary_warped, left_fit, right_fit)
plot_fitted_lane_lines(binary_warped, plot_y, left_fit_x, right_fit_x, left_lane_idx, right_lane_idx)

Finding the curvature

In [82]:
# Define y-value where we want radius of curvature
# Choose the max y value (which corresponds to the bottom fo the image)
def find_curvature(y_eval, fit):
    curvature = ((1 + (2*fit[0]*y_eval + fit[1])**2)**1.5) / np.absolute(2*fit[0])
    return(curvature)

y_eval = np.max(plot_y)
print(binary_warped.shape[0]-1)
left_curve_rad = find_curvature(y_eval, left_fit) 
right_curve_rad = find_curvature(y_eval, right_fit)
print(left_curve_rad, right_curve_rad)
719
9013.31864971 27482.3353914
In [83]:
# Fit new polynomials to x,y in world space

# First convert the nonzero points in pixel space to world space
nonzero = binary_warped.nonzero()
nonzeroy = nonzero[0]
nonzerox = nonzero[1]

# Extract left and right line pixel positions
left_x_m = nonzerox[left_lane_idx] * X_M_PER_PIXEL
left_y_m = nonzeroy[left_lane_idx] * Y_M_PER_PIXEL
right_x_m = nonzerox[right_lane_idx] * X_M_PER_PIXEL
right_y_m = nonzeroy[right_lane_idx] * Y_M_PER_PIXEL 

# Fit a second order polynomial to each
left_fit_m = np.polyfit(left_y_m, left_x_m, 2)
right_fit_m = np.polyfit(right_y_m, right_x_m, 2)

# Find the curvature
y_eval_m = y_eval * Y_M_PER_PIXEL
left_curve_rad_m = find_curvature(y_eval_m, left_fit_m)
right_curve_rad_m = find_curvature(y_eval_m, right_fit_m)
print(left_curve_rad_m, right_curve_rad_m)
3002.2076836 79866.0440547

Finding the offset

In [84]:
def find_offset(left_fit_x, right_fit_x):
    left_line_base_x = left_fit_x[-1]
    right_line_base_x = right_fit_x[-1]
    lane_midpoint_x = (left_line_base_x + right_line_base_x)/2.0
    car_x = 1280/2
    return((car_x - lane_midpoint_x) * X_M_PER_PIXEL)

find_offset(left_fit_x, right_fit_x)
Out[84]:
-0.037353218736630472

Filling in the lane lines

In [85]:
# Drawing the lines back down onto the road

# First create an image to draw on
wrap_zero = np.zeros_like(binary_warped).astype(np.uint8)
color_warp = np.dstack((wrap_zero, wrap_zero, wrap_zero))
In [86]:
# Recast the x and y points into usable format for cv2.fillPoly()
pts_left = np.array([np.transpose(np.vstack([left_fit_x, plot_y]))]) # or use np.dstack instead of np.transpose
pts_right = np.array([np.flipud(np.transpose(np.vstack([right_fit_x, plot_y])))])
pts = np.hstack((pts_left, pts_right))
In [87]:
# Draw the lane onto the warped blank image
cv2.fillPoly(color_warp, np.int_([pts]), (0, 255,0))
new_warp = warper(color_warp, dst, src)
In [88]:
# Plot final result 
result = cv2.addWeighted(sample_image.get_RGB(), 1, new_warp, 0.3, 0)
plt.imshow(result)
Out[88]:
<matplotlib.image.AxesImage at 0x12dba6080>
In [89]:
def fill_lane_lines(original_image, binary_warped, plot_y, left_fit_x, right_fit_x, dst, src):
    
    # First create a blank image
    warp_zero = np.zeros_like(binary_warped).astype(np.uint8)
    color_warped = np.dstack((warp_zero, warp_zero, warp_zero))
    
    # Now format the data in a way that cv2.polyfill works
    pts_left = np.array([np.transpose(np.vstack([left_fit_x, plot_y]))]) # or use np.dstack instead of np.transpose
    pts_right = np.array([np.flipud(np.transpose(np.vstack([right_fit_x, plot_y])))])
    pts = np.hstack((pts_left, pts_right)) 
    
    # Draw the lane onto the warped blank image
    cv2.fillPoly(color_warped, np.int_([pts]), (0, 255,0))
    new_warp = warper(color_warped, dst, src)
    
    result = cv2.addWeighted(original_image, 1, new_warp, 0.3, 0)
    return(result)
In [90]:
# Test to see that the function works
plt.imshow(fill_lane_lines(sample_image.get_RGB(), binary_warped, plot_y, left_fit_x, right_fit_x, dst, src))
Out[90]:
<matplotlib.image.AxesImage at 0x12e409908>

The final image pipeline

First get the distortion matrix for camera

In [91]:
CALIBRATION_FOLDER_NAME = "camera_cal"

# image paths for calibration images
calibration_image_paths = glob.glob(os.path.join(CALIBRATION_FOLDER_NAME, "calibration*.jpg"))

# image path for test image
test_image_path = os.path.join(CALIBRATION_FOLDER_NAME, "test_for_calibration.jpg")

# For the parameters for the calibration
mtx, dist = calibrate_camera(calibration_image_paths, test_image_path, 9, 6)

Define the image to be used

In [92]:
image = lane_line_images[0]
sample_image = ImageWrapper(image, ColorSpace.RGB)
plt.imshow(image)
Out[92]:
<matplotlib.image.AxesImage at 0x12ae8e940>

Now extract the lane lines

In [93]:
binary_warped = warper(get_non_tophat_binary_image(sample_image), src, dst)
binary_warped[:,0:200] = 0
binary_warped[:,1080:1280] = 0
plt.imshow(binary_warped, cmap = 'gray')
Out[93]:
<matplotlib.image.AxesImage at 0x12b9da390>

Get the coefficients for the lane line fits

In [94]:
left_fit, right_fit, right_fit_m, left_fit_m, left_lane_idx, right_lane_idx = find_poly_fit_with_window(binary_warped) 
/Users/kevinlu/miniconda3/envs/carnd-term1/lib/python3.5/site-packages/ipykernel/__main__.py:7: VisibleDeprecationWarning: using a non-integer number instead of an integer will result in an error in the future

Find the curvature

In [95]:
# Convert from pixel space to meters
Y_M_PER_PIXEL = 30/720 # 720 is the height of the image
X_M_PER_PIXEL = 3.7/700 # 700 is the width of the lane in pixel 

y_eval = float(binary_warped.shape[0]-1.0) * Y_M_PER_PIXEL
left_curvature = find_curvature(y_eval, left_fit_m)
right_curvature = find_curvature(y_eval, right_fit_m)

print(left_curvature, right_curvature)
20992.2146038 25194.1935439

Find the offset

In [96]:
offset = find_offset(left_fit_x, right_fit_x)
offset = np.round(offset, 2)
if offset < 0:
    offset_text = str(offset) + " meters left of the center of lane"
else:
    offset_text = str(offset) + " meters right of the center of lane"
print(offset)
print(offset_text)
-0.04
-0.04 meters left of the center of lane

Filling in the lane lines

In [97]:
filled_lane_line_image = fill_lane_lines(sample_image.get_RGB(), binary_warped, plot_y, left_fit_x, right_fit_x, dst, src)

# Write some Text
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(filled_lane_line_image,'Offset is: {0}'.format(offset_text),(50,50), font, 1,(255,255,255),2)
cv2.putText(filled_lane_line_image,'Left curvature is: {0}'.format(left_curvature),(50,100), font, 1,(255,255,255),2)
cv2.putText(filled_lane_line_image,'Right curvature is: {0}'.format(right_curvature),(50,150), font, 1,(255,255,255),2)
    
plt.imshow(filled_lane_line_image)
Out[97]:
<matplotlib.image.AxesImage at 0x129b51d68>
In [98]:
# Define a helper class for us to keep track of the lines

# Convert from pixel space to meters
Y_M_PER_PIXEL = 30/720 # 720 is the height of the image
X_M_PER_PIXEL = 3.7/700 # 700 is the width of the lane in pixel 

class Line():
    def __init__(self, n):
        # was the line detected in the last iteration?
        self.detected = False  
        
        self.num_times_did_not_detect = 0
        
        self.num_threshold_for_initial_search = 5
        
        # x values of the last n fits of the line
        self.recent_x_fitted = [] 
        
        # polynomial coefficients of the last n fits of the line
        self.recent_fit = []
        self.recent_fit_m = []
        
        # polynomial coefficients averaged over the last n iterations
        self._best_fit = None  
        self._best_fit_m = None
        
        # setting the n value
        self.n = n
        
        # polynomial coefficients for the most recent fit
        self.current_fit = []  
        self.current_fit_m = []
        
        # radius of curvature of the line in some units
        self.radius_of_curvature = None 
        
        # distance in meters of vehicle center from the line
        self.line_base_pos = None 
        
        # difference in fit coefficients between last and new fits
        self.diffs = np.array([0,0,0], dtype='float') 
        
        # indexes for the nonzero elements that determine the lane line
        self.non_zero_index = []
    
    @property # equivalent to best_fit = property(best_fit) which is setting the getter 
    def best_fit(self):
#         print("get best fit value")
        self._calculate_best_fit()
#         print(self._best_fit)
        return(self._best_fit)

    def _calculate_best_fit(self):
#         print("calculating best fit")
        fit_coefficients = np.array(self.recent_fit)
        self._best_fit = (np.mean(fit_coefficients, axis = 0))
    
    @property
    def best_fit_m(self):
#         print("get best fit value in meters")
        self._calculate_best_fit_m()
#         print(self._best_fit_m)
        return(self._best_fit_m)
    
    def _calculate_best_fit_m(self):
#         print("calculating best fit value in meters")
        fit_coefficients_m = np.array(self.recent_fit_m)
        self._best_fit_m = (np.mean(fit_coefficients_m, axis = 0))
    
    def did_detect(self):
        self.num_times_did_not_detect = 0
        
    def did_not_detect(self):
        self.num_times_did_not_detect += 1
        
    def determine_if_detected(self):
        if self.num_times_did_not_detect < self.num_threshold_for_initial_search:
            return(True)
        else:
            return(False)
        
    def append_recent_x_fitted(self, x_fit):
        if len(self.recent_x_fitted) >= self.n:
            self.recent_x_fitted.pop(0)
        self.recent_x_fitted.append(x_fit)
    
    def append_recent_fit(self, fit):
        if len(self.recent_fit) >= self.n:
            self.recent_fit.pop(0)
        self.recent_fit.append(fit)
        self.current_fit = fit
    
    def append_recent_fit_m(self, fit_m):
        if len(self.recent_fit) >= self.n:
            self.recent_fit_m.pop(0)
        self.recent_fit_m.append(fit_m)
        self.current_fit_m = fit_m
        
    def append_non_zero_index(self, indexes):
        if len(self.non_zero_index) >= self.n:
             self.non_zero_index.pop(0)
        self.non_zero_index.append(indexes)
        
    def _delete_most_recent_x_fitted(self):
        self.recent_x_fitted.pop()
    
    def _delete_most_recent_fit(self):
        self.recent_fit.pop()
        
    def _delete_most_recent_non_zero_index(self):
        self.non_zero_index.pop()
        
    def delete_data_from_last_frame(self):
        self._delete_most_recent_x_fitted()
        self._delete_most_recent_fit()
        self._delete_most_recent_non_zero_index()
        
    def check_coefficients(self):
        return
#         print(self.diffs)
    
    def _calculate_coefficient_diff(self):
        previous_coefficients = np.array(recent_fit[-2])
        current_coefficients = np.array(self.current_fit)
        self.diffs = current_coefficients - previous_coefficients
    
    
In [104]:
n = 10
left_lane = Line(n)
right_lane = Line(n)

def process_image(image):
    # Wrap the image for easier manipulation
    sample_image = ImageWrapper(image, ColorSpace.RGB)
    
    # Do the binary transform
    binary_warped = warper(get_non_tophat_binary_image(sample_image), src, dst)
    binary_warped[:,0:200] = 0
    binary_warped[:,1080:1280] = 0
    
    # Check if we need to do the initial search again
    if (len(left_lane.recent_fit) == 0 and len(right_lane.recent_fit) == 0\
        and (left_lane.detected == False) and (right_lane.detected == False)):
        print("DIDN'T FIND WINDOW DOING INITIAL SEARCH AGAIN!")
        # Find the left and right fits, and also their associated indexes
        left_fit, right_fit, left_fit_m, right_fit_m,_,_ = find_poly_fit_with_window(binary_warped) 
    else:
        # In the case that we don't have to do the initial search use the previous fits
        # to determine the current fit
        recent_left_fit = left_lane.recent_fit[-1]
        recent_right_fit = right_lane.recent_fit[-1] 
        left_fit, right_fit, left_fit_m, right_fit_m,_,_ = find_poly_fit_after_initial_window(binary_warped, \
                                                                                         recent_left_fit, \
                                                                                         recent_right_fit) 

#     # Calculate the values needed to check if the lines that were found are good
    plot_y, left_fit_x, right_fit_x = get_fitted_lines(binary_warped, left_fit, right_fit)

    if ((check_lane_width(left_fit_x, right_fit_x) == False) or (check_parallel(left_fit_x, right_fit_x) == False)):
        print("Lanes weren't detected")
        # If the lanes detected aren't good then don't append the data to the lane
        left_lane.detected = False
        right_lane.detected = False
        
        if(len(left_lane.recent_fit) == 0 and len(right_lane.recent_fit) == 0):
            return(sample_image.get_RGB())
    else:
        print("Lanes were detected")
        # If the lanes that detected are value lanes, then append them to the data
        left_lane.detected = True
        right_lane.detected = True
        
        # Append the new fits
        left_lane.append_recent_fit(left_fit)
        right_lane.append_recent_fit(right_fit)
        left_lane.append_recent_fit_m(left_fit_m)
        right_lane.append_recent_fit_m(right_fit_m)
        
        # Calculate the x values using the best fit
        plot_y, left_fit_x, right_fit_x = get_fitted_lines(binary_warped, left_lane.best_fit, right_lane.best_fit)
        
        # Add the calculated values
        left_lane.append_recent_x_fitted(left_fit_x)
        right_lane.append_recent_x_fitted(right_fit_x)
    
    # Calculate the curvatures
    y_eval = float(binary_warped.shape[0]-1.0) * Y_M_PER_PIXEL
    left_curvature = find_curvature(y_eval, left_lane.best_fit_m)
    right_curvature = find_curvature(y_eval, right_lane.best_fit_m)
    
    # Find the offset
    recent_left_lane_x_fitted = left_lane.recent_x_fitted[-1]
    recent_right_lane_x_fitted = right_lane.recent_x_fitted[-1]
    offset = find_offset(recent_left_lane_x_fitted, recent_right_lane_x_fitted)
    offset = np.round(offset, 2)
    
    if offset < 0:
        offset_text = str(abs(offset)) + " meters left of the center of lane"
    else:
        offset_text = str(abs(offset)) + " meters right of the center of lane"
        
    # Fill in the lane line
    filled_lane_line_image = fill_lane_lines(sample_image.get_RGB(), binary_warped, plot_y, \
                                            recent_left_lane_x_fitted, recent_right_lane_x_fitted,\
                                             dst, src)
    
    # Write some Text
    font = cv2.FONT_HERSHEY_SIMPLEX
    cv2.putText(filled_lane_line_image,'Offset is: {0}'.format(offset_text),(50,50), font, 1,(255,255,255),2)
    cv2.putText(filled_lane_line_image,'Left curvature is: {0}'.format(left_curvature),(50,100), font, 1,(255,255,255),2)
    cv2.putText(filled_lane_line_image,'Right curvature is: {0}'.format(right_curvature),(50,150), font, 1,(255,255,255),2)

    return(filled_lane_line_image) 

def check_lane_width(left_fit_x, right_fit_x):
    lane_width = find_lane_width(left_fit_x, right_fit_x)
#     print("lane_width is {0}".format(lane_width))
    if (2 < lane_width < 4):
        return(True)
    else:
        return(False)

def find_lane_width(left_fit_x, right_fit_x, in_meters = True):
#     print(left_fit_x)
    left_lane_base_x = left_fit_x[-1]
    right_lane_base_x = right_fit_x[-1]
    if in_meters:
        return((right_lane_base_x - left_lane_base_x) * X_M_PER_PIXEL) 
    else:
        return(right_lane_base_x - left_lane_base_x)
    
    
def check_parallel(left_fit_x, right_fit_x):
    initial_width = find_lane_width(left_fit_x, right_fit_x)
    for i in range(len(left_fit_x)):
        diff = (right_fit_x[i] - left_fit_x[i]) * X_M_PER_PIXEL
        if abs(diff-initial_width) > 0.5:
            return(False)
    return(True)
In [105]:
processed_image = process_image(lane_line_images[0])
plt.imshow(processed_image)
DIDN'T FIND WINDOW DOING INITIAL SEARCH AGAIN!
Lanes were detected
Out[105]:
<matplotlib.image.AxesImage at 0x14301bbe0>
In [106]:
# Import everything needed to edit/save/watch video clips
from moviepy.editor import VideoFileClip
from IPython.display import HTML
project_video_output = 'project_video_result.mp4'
clip1 = VideoFileClip("project_video.mp4")
project_video_clip = clip1.fl_image(process_image) #NOTE: this function expects color images!!
%time project_video_clip.write_videofile(project_video_output, audio=False)
Lanes were detected
[MoviePy] >>>> Building video project_video_result.mp4
[MoviePy] Writing video project_video_result.mp4
  0%|          | 0/1261 [00:00<?, ?it/s]
  0%|          | 1/1261 [00:00<18:05,  1.16it/s]
Lanes were detected
  0%|          | 2/1261 [00:02<20:30,  1.02it/s]
Lanes were detected
  0%|          | 3/1261 [00:02<19:52,  1.06it/s]
Lanes were detected
  0%|          | 4/1261 [00:03<18:45,  1.12it/s]
Lanes were detected
  0%|          | 5/1261 [00:04<17:58,  1.16it/s]
Lanes were detected
  0%|          | 6/1261 [00:05<17:27,  1.20it/s]
Lanes were detected
  1%|          | 7/1261 [00:06<17:06,  1.22it/s]
Lanes were detected
  1%|          | 8/1261 [00:06<16:44,  1.25it/s]
Lanes were detected
  1%|          | 9/1261 [00:07<16:36,  1.26it/s]
Lanes were detected
  1%|          | 10/1261 [00:08<16:38,  1.25it/s]
Lanes were detected
  1%|          | 11/1261 [00:09<16:32,  1.26it/s]
Lanes were detected
  1%|          | 12/1261 [00:10<17:57,  1.16it/s]
Lanes were detected
  1%|          | 13/1261 [00:11<18:54,  1.10it/s]
Lanes were detected
  1%|          | 14/1261 [00:12<20:53,  1.00s/it]
Lanes were detected
  1%|          | 15/1261 [00:13<21:52,  1.05s/it]
Lanes were detected
  1%|▏         | 16/1261 [00:14<20:28,  1.01it/s]
Lanes were detected
  1%|▏         | 17/1261 [00:15<20:28,  1.01it/s]
Lanes were detected
  1%|▏         | 18/1261 [00:16<19:53,  1.04it/s]
Lanes were detected
  2%|▏         | 19/1261 [00:17<19:04,  1.08it/s]
Lanes were detected
  2%|▏         | 20/1261 [00:18<18:31,  1.12it/s]
Lanes were detected
  2%|▏         | 21/1261 [00:18<17:57,  1.15it/s]
Lanes were detected
  2%|▏         | 22/1261 [00:20<20:08,  1.03it/s]
Lanes were detected
  2%|▏         | 23/1261 [00:20<19:09,  1.08it/s]
Lanes were detected
  2%|▏         | 24/1261 [00:21<19:04,  1.08it/s]
Lanes were detected
  2%|▏         | 25/1261 [00:22<19:19,  1.07it/s]
Lanes were detected
  2%|▏         | 26/1261 [00:23<18:56,  1.09it/s]
Lanes were detected
  2%|▏         | 27/1261 [00:24<19:17,  1.07it/s]
Lanes were detected
  2%|▏         | 28/1261 [00:25<19:11,  1.07it/s]
Lanes were detected
  2%|▏         | 29/1261 [00:26<18:16,  1.12it/s]
Lanes were detected
  2%|▏         | 30/1261 [00:27<17:54,  1.15it/s]
Lanes were detected
  2%|▏         | 31/1261 [00:28<18:12,  1.13it/s]
Lanes were detected
  3%|▎         | 32/1261 [00:28<18:08,  1.13it/s]
Lanes were detected
  3%|▎         | 33/1261 [00:29<17:41,  1.16it/s]
Lanes were detected
  3%|▎         | 34/1261 [00:30<18:15,  1.12it/s]
Lanes were detected
  3%|▎         | 35/1261 [00:31<19:22,  1.05it/s]
Lanes were detected
  3%|▎         | 36/1261 [00:32<19:04,  1.07it/s]
Lanes were detected
  3%|▎         | 37/1261 [00:33<18:52,  1.08it/s]
Lanes were detected
  3%|▎         | 38/1261 [00:34<18:43,  1.09it/s]
Lanes were detected
  3%|▎         | 39/1261 [00:35<19:09,  1.06it/s]
Lanes were detected
  3%|▎         | 40/1261 [00:36<19:49,  1.03it/s]
Lanes were detected
  3%|▎         | 41/1261 [00:37<19:43,  1.03it/s]
Lanes were detected
  3%|▎         | 42/1261 [00:38<20:01,  1.01it/s]
Lanes were detected
  3%|▎         | 43/1261 [00:39<20:29,  1.01s/it]
Lanes were detected
  3%|▎         | 44/1261 [00:40<19:33,  1.04it/s]
Lanes were detected
  4%|▎         | 45/1261 [00:41<19:44,  1.03it/s]
Lanes were detected
  4%|▎         | 46/1261 [00:42<19:10,  1.06it/s]
Lanes were detected
  4%|▎         | 47/1261 [00:43<19:25,  1.04it/s]
Lanes were detected
  4%|▍         | 48/1261 [00:44<19:22,  1.04it/s]
Lanes were detected
  4%|▍         | 49/1261 [00:45<18:54,  1.07it/s]
Lanes were detected
  4%|▍         | 50/1261 [00:46<18:31,  1.09it/s]
Lanes were detected
  4%|▍         | 51/1261 [00:46<18:28,  1.09it/s]
Lanes were detected
  4%|▍         | 52/1261 [00:47<18:01,  1.12it/s]
Lanes were detected
  4%|▍         | 53/1261 [00:48<17:38,  1.14it/s]
Lanes were detected
  4%|▍         | 54/1261 [00:49<17:29,  1.15it/s]
Lanes were detected
  4%|▍         | 55/1261 [00:50<18:41,  1.08it/s]
Lanes were detected
  4%|▍         | 56/1261 [00:51<20:20,  1.01s/it]
Lanes were detected
  5%|▍         | 57/1261 [00:52<20:58,  1.05s/it]
Lanes were detected
  5%|▍         | 58/1261 [00:54<22:43,  1.13s/it]
Lanes were detected
  5%|▍         | 59/1261 [00:55<25:27,  1.27s/it]
Lanes were detected
  5%|▍         | 60/1261 [00:56<24:36,  1.23s/it]
Lanes were detected
  5%|▍         | 61/1261 [00:58<25:03,  1.25s/it]
Lanes were detected
  5%|▍         | 62/1261 [00:59<22:59,  1.15s/it]
Lanes were detected
  5%|▍         | 63/1261 [01:00<21:39,  1.08s/it]
Lanes were detected
  5%|▌         | 64/1261 [01:01<20:44,  1.04s/it]
Lanes were detected
  5%|▌         | 65/1261 [01:02<20:12,  1.01s/it]
Lanes were detected
  5%|▌         | 66/1261 [01:02<19:49,  1.00it/s]
Lanes were detected
  5%|▌         | 67/1261 [01:04<25:34,  1.28s/it]
Lanes were detected
  5%|▌         | 68/1261 [01:06<29:37,  1.49s/it]
Lanes were detected
  5%|▌         | 69/1261 [01:08<27:58,  1.41s/it]
Lanes were detected
  6%|▌         | 70/1261 [01:09<25:39,  1.29s/it]
Lanes were detected
  6%|▌         | 71/1261 [01:10<24:14,  1.22s/it]
Lanes were detected
  6%|▌         | 72/1261 [01:11<22:28,  1.13s/it]
Lanes were detected
  6%|▌         | 73/1261 [01:12<21:40,  1.10s/it]
Lanes were detected
  6%|▌         | 74/1261 [01:13<20:39,  1.04s/it]
Lanes were detected
  6%|▌         | 75/1261 [01:13<19:31,  1.01it/s]
Lanes were detected
  6%|▌         | 76/1261 [01:15<20:31,  1.04s/it]
Lanes were detected
  6%|▌         | 77/1261 [01:16<19:57,  1.01s/it]
Lanes were detected
  6%|▌         | 78/1261 [01:16<19:22,  1.02it/s]
Lanes were detected
  6%|▋         | 79/1261 [01:17<19:02,  1.03it/s]
Lanes were detected
  6%|▋         | 80/1261 [01:19<20:23,  1.04s/it]
Lanes were detected
  6%|▋         | 81/1261 [01:20<23:03,  1.17s/it]
Lanes were detected
  7%|▋         | 82/1261 [01:21<21:49,  1.11s/it]
Lanes were detected
  7%|▋         | 83/1261 [01:22<22:07,  1.13s/it]
Lanes were detected
  7%|▋         | 84/1261 [01:23<22:44,  1.16s/it]
Lanes were detected
  7%|▋         | 85/1261 [01:24<21:50,  1.11s/it]
Lanes were detected
  7%|▋         | 86/1261 [01:25<20:55,  1.07s/it]
Lanes were detected
  7%|▋         | 87/1261 [01:26<20:16,  1.04s/it]
Lanes were detected
  7%|▋         | 88/1261 [01:27<19:29,  1.00it/s]
Lanes were detected
  7%|▋         | 89/1261 [01:28<18:28,  1.06it/s]
Lanes were detected
  7%|▋         | 90/1261 [01:29<18:27,  1.06it/s]
Lanes were detected
  7%|▋         | 91/1261 [01:30<18:16,  1.07it/s]
Lanes were detected
  7%|▋         | 92/1261 [01:31<18:52,  1.03it/s]
Lanes were detected
  7%|▋         | 93/1261 [01:32<18:29,  1.05it/s]
Lanes were detected
  7%|▋         | 94/1261 [01:33<18:09,  1.07it/s]
Lanes were detected
  8%|▊         | 95/1261 [01:34<17:54,  1.08it/s]
Lanes were detected
  8%|▊         | 96/1261 [01:35<19:27,  1.00s/it]
Lanes were detected
  8%|▊         | 97/1261 [01:36<19:49,  1.02s/it]
Lanes were detected
  8%|▊         | 98/1261 [01:37<20:44,  1.07s/it]
Lanes were detected
  8%|▊         | 99/1261 [01:39<23:21,  1.21s/it]
Lanes were detected
  8%|▊         | 100/1261 [01:40<23:34,  1.22s/it]
Lanes were detected
  8%|▊         | 101/1261 [01:41<22:27,  1.16s/it]
Lanes were detected
  8%|▊         | 102/1261 [01:42<22:10,  1.15s/it]
Lanes were detected
  8%|▊         | 103/1261 [01:43<23:18,  1.21s/it]
Lanes were detected
  8%|▊         | 104/1261 [01:45<25:24,  1.32s/it]
Lanes were detected
  8%|▊         | 105/1261 [01:46<25:11,  1.31s/it]
Lanes were detected
  8%|▊         | 106/1261 [01:47<23:01,  1.20s/it]
Lanes were detected
  8%|▊         | 107/1261 [01:49<24:38,  1.28s/it]
Lanes were detected
  9%|▊         | 108/1261 [01:50<26:02,  1.35s/it]
Lanes were detected
  9%|▊         | 109/1261 [01:51<24:54,  1.30s/it]
Lanes were detected
  9%|▊         | 110/1261 [01:52<23:01,  1.20s/it]
Lanes were detected
  9%|▉         | 111/1261 [01:53<22:14,  1.16s/it]
Lanes were detected
  9%|▉         | 112/1261 [01:55<22:12,  1.16s/it]
Lanes were detected
  9%|▉         | 113/1261 [01:56<21:40,  1.13s/it]
Lanes were detected
  9%|▉         | 114/1261 [01:57<20:56,  1.10s/it]
Lanes were detected
  9%|▉         | 115/1261 [01:58<20:06,  1.05s/it]
Lanes were detected
  9%|▉         | 116/1261 [01:59<19:31,  1.02s/it]
Lanes were detected
  9%|▉         | 117/1261 [02:00<20:06,  1.05s/it]
Lanes were detected
  9%|▉         | 118/1261 [02:01<19:51,  1.04s/it]
Lanes were detected
  9%|▉         | 119/1261 [02:02<19:52,  1.04s/it]
Lanes were detected
 10%|▉         | 120/1261 [02:03<19:54,  1.05s/it]
Lanes were detected
 10%|▉         | 121/1261 [02:04<20:07,  1.06s/it]
Lanes were detected
 10%|▉         | 122/1261 [02:05<19:26,  1.02s/it]
Lanes were detected
 10%|▉         | 123/1261 [02:06<19:12,  1.01s/it]
Lanes were detected
 10%|▉         | 124/1261 [02:07<19:24,  1.02s/it]
Lanes were detected
 10%|▉         | 125/1261 [02:08<19:21,  1.02s/it]
Lanes were detected
 10%|▉         | 126/1261 [02:09<20:03,  1.06s/it]
Lanes were detected
 10%|█         | 127/1261 [02:11<23:19,  1.23s/it]
Lanes were detected
 10%|█         | 128/1261 [02:12<25:17,  1.34s/it]
Lanes were detected
 10%|█         | 129/1261 [02:14<25:39,  1.36s/it]
Lanes were detected
 10%|█         | 130/1261 [02:15<25:15,  1.34s/it]
Lanes were detected
 10%|█         | 131/1261 [02:16<24:50,  1.32s/it]
Lanes were detected
 10%|█         | 132/1261 [02:17<23:17,  1.24s/it]
Lanes were detected
 11%|█         | 133/1261 [02:19<24:26,  1.30s/it]
Lanes were detected
 11%|█         | 134/1261 [02:21<28:04,  1.49s/it]
Lanes were detected
 11%|█         | 135/1261 [02:22<27:48,  1.48s/it]
Lanes were detected
 11%|█         | 136/1261 [02:23<27:13,  1.45s/it]
Lanes were detected
 11%|█         | 137/1261 [02:25<25:16,  1.35s/it]
Lanes were detected
 11%|█         | 138/1261 [02:26<23:34,  1.26s/it]
Lanes were detected
 11%|█         | 139/1261 [02:27<22:52,  1.22s/it]
Lanes were detected
 11%|█         | 140/1261 [02:28<22:34,  1.21s/it]
Lanes were detected
 11%|█         | 141/1261 [02:29<22:23,  1.20s/it]
Lanes were detected
 11%|█▏        | 142/1261 [02:30<22:24,  1.20s/it]
Lanes were detected
 11%|█▏        | 143/1261 [02:31<21:55,  1.18s/it]
Lanes were detected
 11%|█▏        | 144/1261 [02:32<20:23,  1.10s/it]
Lanes were detected
 11%|█▏        | 145/1261 [02:33<19:33,  1.05s/it]
Lanes were detected
 12%|█▏        | 146/1261 [02:34<18:46,  1.01s/it]
Lanes were detected
 12%|█▏        | 147/1261 [02:35<18:18,  1.01it/s]
Lanes were detected
 12%|█▏        | 148/1261 [02:36<17:47,  1.04it/s]
Lanes were detected
 12%|█▏        | 149/1261 [02:37<17:35,  1.05it/s]
Lanes were detected
 12%|█▏        | 150/1261 [02:38<18:35,  1.00s/it]
Lanes were detected
 12%|█▏        | 151/1261 [02:39<17:58,  1.03it/s]
Lanes were detected
 12%|█▏        | 152/1261 [02:40<18:06,  1.02it/s]
Lanes were detected
 12%|█▏        | 153/1261 [02:41<19:33,  1.06s/it]
Lanes were detected
 12%|█▏        | 154/1261 [02:42<20:04,  1.09s/it]
Lanes were detected
 12%|█▏        | 155/1261 [02:44<22:45,  1.23s/it]
Lanes were detected
 12%|█▏        | 156/1261 [02:46<24:28,  1.33s/it]
Lanes were detected
 12%|█▏        | 157/1261 [02:47<23:37,  1.28s/it]
Lanes were detected
 13%|█▎        | 158/1261 [02:48<22:52,  1.24s/it]
Lanes were detected
 13%|█▎        | 159/1261 [02:49<22:29,  1.22s/it]
Lanes were detected
 13%|█▎        | 160/1261 [02:50<22:44,  1.24s/it]
Lanes were detected
 13%|█▎        | 161/1261 [02:52<23:06,  1.26s/it]
Lanes were detected
 13%|█▎        | 162/1261 [02:53<22:15,  1.22s/it]
Lanes were detected
 13%|█▎        | 163/1261 [02:54<20:37,  1.13s/it]
Lanes were detected
 13%|█▎        | 164/1261 [02:55<19:27,  1.06s/it]
Lanes were detected
 13%|█▎        | 165/1261 [02:56<18:36,  1.02s/it]
Lanes were detected
 13%|█▎        | 166/1261 [02:56<17:50,  1.02it/s]
Lanes were detected
 13%|█▎        | 167/1261 [02:57<17:15,  1.06it/s]
Lanes were detected
 13%|█▎        | 168/1261 [02:58<16:50,  1.08it/s]
Lanes were detected
 13%|█▎        | 169/1261 [02:59<16:35,  1.10it/s]
Lanes were detected
 13%|█▎        | 170/1261 [03:00<16:52,  1.08it/s]
Lanes were detected
 14%|█▎        | 171/1261 [03:01<16:38,  1.09it/s]
Lanes were detected
 14%|█▎        | 172/1261 [03:02<16:37,  1.09it/s]
Lanes were detected
 14%|█▎        | 173/1261 [03:03<16:36,  1.09it/s]
Lanes were detected
 14%|█▍        | 174/1261 [03:04<16:28,  1.10it/s]
Lanes were detected
 14%|█▍        | 175/1261 [03:04<16:19,  1.11it/s]
Lanes were detected
 14%|█▍        | 176/1261 [03:05<16:23,  1.10it/s]
Lanes were detected
 14%|█▍        | 177/1261 [03:06<16:52,  1.07it/s]
Lanes were detected
 14%|█▍        | 178/1261 [03:08<18:07,  1.00s/it]
Lanes were detected
 14%|█▍        | 179/1261 [03:09<19:46,  1.10s/it]
Lanes were detected
 14%|█▍        | 180/1261 [03:10<22:18,  1.24s/it]
Lanes were detected
 14%|█▍        | 181/1261 [03:12<23:31,  1.31s/it]
Lanes were detected
 14%|█▍        | 182/1261 [03:13<22:02,  1.23s/it]
Lanes were detected
 15%|█▍        | 183/1261 [03:14<20:53,  1.16s/it]
Lanes were detected
 15%|█▍        | 184/1261 [03:15<19:42,  1.10s/it]
Lanes were detected
 15%|█▍        | 185/1261 [03:16<18:45,  1.05s/it]
Lanes were detected
 15%|█▍        | 186/1261 [03:17<19:54,  1.11s/it]
Lanes were detected
 15%|█▍        | 187/1261 [03:18<20:31,  1.15s/it]
Lanes were detected
 15%|█▍        | 188/1261 [03:20<21:29,  1.20s/it]
Lanes were detected
 15%|█▍        | 189/1261 [03:21<22:02,  1.23s/it]
Lanes were detected
 15%|█▌        | 190/1261 [03:22<22:09,  1.24s/it]
Lanes were detected
 15%|█▌        | 191/1261 [03:24<22:39,  1.27s/it]
Lanes were detected
 15%|█▌        | 192/1261 [03:25<23:06,  1.30s/it]
Lanes were detected
 15%|█▌        | 193/1261 [03:26<22:19,  1.25s/it]
Lanes were detected
 15%|█▌        | 194/1261 [03:27<21:04,  1.19s/it]
Lanes were detected
 15%|█▌        | 195/1261 [03:28<19:47,  1.11s/it]
Lanes were detected
 16%|█▌        | 196/1261 [03:29<18:37,  1.05s/it]
Lanes were detected
 16%|█▌        | 197/1261 [03:30<17:59,  1.01s/it]
Lanes were detected
 16%|█▌        | 198/1261 [03:31<18:19,  1.03s/it]
Lanes were detected
 16%|█▌        | 199/1261 [03:32<18:40,  1.05s/it]
Lanes were detected
 16%|█▌        | 200/1261 [03:33<17:47,  1.01s/it]
Lanes were detected
 16%|█▌        | 201/1261 [03:34<17:31,  1.01it/s]
Lanes were detected
 16%|█▌        | 202/1261 [03:35<16:59,  1.04it/s]
Lanes were detected
 16%|█▌        | 203/1261 [03:36<18:19,  1.04s/it]
Lanes were detected
 16%|█▌        | 204/1261 [03:37<17:42,  1.01s/it]
Lanes were detected
 16%|█▋        | 205/1261 [03:38<18:26,  1.05s/it]
Lanes were detected
 16%|█▋        | 206/1261 [03:39<18:22,  1.05s/it]
Lanes were detected
 16%|█▋        | 207/1261 [03:40<17:48,  1.01s/it]
Lanes were detected
 16%|█▋        | 208/1261 [03:41<18:17,  1.04s/it]
Lanes were detected
 17%|█▋        | 209/1261 [03:43<20:15,  1.16s/it]
Lanes were detected
 17%|█▋        | 210/1261 [03:44<20:25,  1.17s/it]
Lanes were detected
 17%|█▋        | 211/1261 [03:45<19:19,  1.10s/it]
Lanes were detected
 17%|█▋        | 212/1261 [03:46<18:33,  1.06s/it]
Lanes were detected
 17%|█▋        | 213/1261 [03:47<18:47,  1.08s/it]
Lanes were detected
 17%|█▋        | 214/1261 [03:48<17:58,  1.03s/it]
Lanes were detected
 17%|█▋        | 215/1261 [03:49<17:08,  1.02it/s]
Lanes were detected
 17%|█▋        | 216/1261 [03:50<16:42,  1.04it/s]
Lanes were detected
 17%|█▋        | 217/1261 [03:51<17:02,  1.02it/s]
Lanes were detected
 17%|█▋        | 218/1261 [03:52<17:23,  1.00s/it]
Lanes were detected
 17%|█▋        | 219/1261 [03:53<17:30,  1.01s/it]
Lanes were detected
 17%|█▋        | 220/1261 [03:54<17:24,  1.00s/it]
Lanes were detected
 18%|█▊        | 221/1261 [03:55<17:00,  1.02it/s]
Lanes were detected
 18%|█▊        | 222/1261 [03:55<16:16,  1.06it/s]
Lanes were detected
 18%|█▊        | 223/1261 [03:56<15:34,  1.11it/s]
Lanes were detected
 18%|█▊        | 224/1261 [03:57<15:06,  1.14it/s]
Lanes were detected
 18%|█▊        | 225/1261 [03:58<14:44,  1.17it/s]
Lanes were detected
 18%|█▊        | 226/1261 [03:59<14:33,  1.18it/s]
Lanes were detected
 18%|█▊        | 227/1261 [03:59<14:22,  1.20it/s]
Lanes were detected
 18%|█▊        | 228/1261 [04:00<14:18,  1.20it/s]
Lanes were detected
 18%|█▊        | 229/1261 [04:01<14:08,  1.22it/s]
Lanes were detected
 18%|█▊        | 230/1261 [04:02<14:04,  1.22it/s]
Lanes were detected
 18%|█▊        | 231/1261 [04:03<13:56,  1.23it/s]
Lanes were detected
 18%|█▊        | 232/1261 [04:04<13:58,  1.23it/s]
Lanes were detected
 18%|█▊        | 233/1261 [04:04<13:54,  1.23it/s]
Lanes were detected
 19%|█▊        | 234/1261 [04:05<13:51,  1.23it/s]
Lanes were detected
 19%|█▊        | 235/1261 [04:06<13:49,  1.24it/s]
Lanes were detected
 19%|█▊        | 236/1261 [04:07<14:05,  1.21it/s]
Lanes were detected
 19%|█▉        | 237/1261 [04:08<14:08,  1.21it/s]
Lanes were detected
 19%|█▉        | 238/1261 [04:08<14:04,  1.21it/s]
Lanes were detected
 19%|█▉        | 239/1261 [04:09<14:10,  1.20it/s]
Lanes were detected
 19%|█▉        | 240/1261 [04:10<15:21,  1.11it/s]
Lanes were detected
 19%|█▉        | 241/1261 [04:11<15:27,  1.10it/s]
Lanes were detected
 19%|█▉        | 242/1261 [04:12<15:26,  1.10it/s]
Lanes were detected
 19%|█▉        | 243/1261 [04:13<15:17,  1.11it/s]
Lanes were detected
 19%|█▉        | 244/1261 [04:14<14:49,  1.14it/s]
Lanes were detected
 19%|█▉        | 245/1261 [04:15<14:31,  1.17it/s]
Lanes were detected
 20%|█▉        | 246/1261 [04:16<14:12,  1.19it/s]
Lanes were detected
 20%|█▉        | 247/1261 [04:16<14:04,  1.20it/s]
Lanes were detected
 20%|█▉        | 248/1261 [04:17<13:55,  1.21it/s]
Lanes were detected
 20%|█▉        | 249/1261 [04:18<13:54,  1.21it/s]
Lanes were detected
 20%|█▉        | 250/1261 [04:19<14:12,  1.19it/s]
Lanes were detected
 20%|█▉        | 251/1261 [04:20<15:04,  1.12it/s]
Lanes were detected
 20%|█▉        | 252/1261 [04:21<14:58,  1.12it/s]
Lanes were detected
 20%|██        | 253/1261 [04:22<14:53,  1.13it/s]
Lanes were detected
 20%|██        | 254/1261 [04:23<16:33,  1.01it/s]
Lanes were detected
 20%|██        | 255/1261 [04:24<18:14,  1.09s/it]
Lanes were detected
 20%|██        | 256/1261 [04:25<18:06,  1.08s/it]
Lanes were detected
 20%|██        | 257/1261 [04:26<17:37,  1.05s/it]
Lanes were detected
 20%|██        | 258/1261 [04:27<17:27,  1.04s/it]
Lanes were detected
 21%|██        | 259/1261 [04:28<17:47,  1.07s/it]
Lanes were detected
 21%|██        | 260/1261 [04:29<17:23,  1.04s/it]
Lanes were detected
 21%|██        | 261/1261 [04:30<16:56,  1.02s/it]
Lanes were detected
 21%|██        | 262/1261 [04:31<15:57,  1.04it/s]
Lanes were detected
 21%|██        | 263/1261 [04:32<15:18,  1.09it/s]
Lanes were detected
 21%|██        | 264/1261 [04:33<14:58,  1.11it/s]
Lanes were detected
 21%|██        | 265/1261 [04:34<14:58,  1.11it/s]
Lanes were detected
 21%|██        | 266/1261 [04:35<14:48,  1.12it/s]
Lanes were detected
 21%|██        | 267/1261 [04:36<15:16,  1.08it/s]
Lanes were detected
 21%|██▏       | 268/1261 [04:37<15:24,  1.07it/s]
Lanes were detected
 21%|██▏       | 269/1261 [04:38<15:53,  1.04it/s]
Lanes were detected
 21%|██▏       | 270/1261 [04:39<19:46,  1.20s/it]
Lanes were detected
 21%|██▏       | 271/1261 [04:41<21:47,  1.32s/it]
Lanes were detected
 22%|██▏       | 272/1261 [04:42<20:41,  1.26s/it]
Lanes were detected
 22%|██▏       | 273/1261 [04:43<19:45,  1.20s/it]
Lanes were detected
 22%|██▏       | 274/1261 [04:44<19:03,  1.16s/it]
Lanes were detected
 22%|██▏       | 275/1261 [04:45<18:22,  1.12s/it]
Lanes were detected
 22%|██▏       | 276/1261 [04:46<17:37,  1.07s/it]
Lanes were detected
 22%|██▏       | 277/1261 [04:47<17:12,  1.05s/it]
Lanes were detected
 22%|██▏       | 278/1261 [04:48<18:21,  1.12s/it]
Lanes were detected
 22%|██▏       | 279/1261 [04:50<19:03,  1.16s/it]
Lanes were detected
 22%|██▏       | 280/1261 [04:51<18:08,  1.11s/it]
Lanes were detected
 22%|██▏       | 281/1261 [04:52<18:20,  1.12s/it]
Lanes were detected
 22%|██▏       | 282/1261 [04:53<18:36,  1.14s/it]
Lanes were detected
 22%|██▏       | 283/1261 [04:54<18:32,  1.14s/it]
Lanes were detected
 23%|██▎       | 284/1261 [04:55<18:13,  1.12s/it]
Lanes were detected
 23%|██▎       | 285/1261 [04:56<18:45,  1.15s/it]
Lanes were detected
 23%|██▎       | 286/1261 [04:57<18:07,  1.12s/it]
Lanes were detected
 23%|██▎       | 287/1261 [04:59<17:49,  1.10s/it]
Lanes were detected
 23%|██▎       | 288/1261 [04:59<17:03,  1.05s/it]
Lanes were detected
 23%|██▎       | 289/1261 [05:00<16:17,  1.01s/it]
Lanes were detected
 23%|██▎       | 290/1261 [05:01<15:35,  1.04it/s]
Lanes were detected
 23%|██▎       | 291/1261 [05:02<14:54,  1.08it/s]
Lanes were detected
 23%|██▎       | 292/1261 [05:03<14:29,  1.11it/s]
Lanes were detected
 23%|██▎       | 293/1261 [05:04<14:27,  1.12it/s]
Lanes were detected
 23%|██▎       | 294/1261 [05:05<13:54,  1.16it/s]
Lanes were detected
 23%|██▎       | 295/1261 [05:05<13:28,  1.19it/s]
Lanes were detected
 23%|██▎       | 296/1261 [05:06<13:18,  1.21it/s]
Lanes were detected
 24%|██▎       | 297/1261 [05:07<13:13,  1.22it/s]
Lanes were detected
 24%|██▎       | 298/1261 [05:08<13:12,  1.22it/s]
Lanes were detected
 24%|██▎       | 299/1261 [05:09<13:19,  1.20it/s]
Lanes were detected
 24%|██▍       | 300/1261 [05:10<13:58,  1.15it/s]
Lanes were detected
 24%|██▍       | 301/1261 [05:11<14:20,  1.12it/s]
Lanes were detected
 24%|██▍       | 302/1261 [05:11<13:57,  1.15it/s]
Lanes were detected
 24%|██▍       | 303/1261 [05:12<13:29,  1.18it/s]
Lanes were detected
 24%|██▍       | 304/1261 [05:13<13:11,  1.21it/s]
Lanes were detected
 24%|██▍       | 305/1261 [05:14<12:53,  1.24it/s]
Lanes were detected
 24%|██▍       | 306/1261 [05:15<12:49,  1.24it/s]
Lanes were detected
 24%|██▍       | 307/1261 [05:15<12:59,  1.22it/s]
Lanes were detected
 24%|██▍       | 308/1261 [05:16<13:08,  1.21it/s]
Lanes were detected
 25%|██▍       | 309/1261 [05:17<12:39,  1.25it/s]
Lanes were detected
 25%|██▍       | 310/1261 [05:18<12:24,  1.28it/s]
Lanes were detected
 25%|██▍       | 311/1261 [05:18<12:12,  1.30it/s]
Lanes were detected
 25%|██▍       | 312/1261 [05:19<12:48,  1.24it/s]
Lanes were detected
 25%|██▍       | 313/1261 [05:20<14:12,  1.11it/s]
Lanes were detected
 25%|██▍       | 314/1261 [05:21<13:50,  1.14it/s]
Lanes were detected
 25%|██▍       | 315/1261 [05:22<13:48,  1.14it/s]
Lanes were detected
 25%|██▌       | 316/1261 [05:23<14:10,  1.11it/s]
Lanes were detected
 25%|██▌       | 317/1261 [05:24<14:51,  1.06it/s]
Lanes were detected
 25%|██▌       | 318/1261 [05:25<16:09,  1.03s/it]
Lanes were detected
 25%|██▌       | 319/1261 [05:26<16:04,  1.02s/it]
Lanes were detected
 25%|██▌       | 320/1261 [05:27<16:01,  1.02s/it]
Lanes were detected
 25%|██▌       | 321/1261 [05:28<15:49,  1.01s/it]
Lanes were detected
 26%|██▌       | 322/1261 [05:29<15:57,  1.02s/it]
Lanes were detected
 26%|██▌       | 323/1261 [05:30<15:49,  1.01s/it]
Lanes were detected
 26%|██▌       | 324/1261 [05:31<15:40,  1.00s/it]
Lanes were detected
 26%|██▌       | 325/1261 [05:32<15:10,  1.03it/s]
Lanes were detected
 26%|██▌       | 326/1261 [05:33<14:40,  1.06it/s]
Lanes were detected
 26%|██▌       | 327/1261 [05:34<14:06,  1.10it/s]
Lanes were detected
 26%|██▌       | 328/1261 [05:35<13:46,  1.13it/s]
Lanes were detected
 26%|██▌       | 329/1261 [05:36<13:35,  1.14it/s]
Lanes were detected
 26%|██▌       | 330/1261 [05:37<13:22,  1.16it/s]
Lanes were detected
 26%|██▌       | 331/1261 [05:37<13:21,  1.16it/s]
Lanes were detected
 26%|██▋       | 332/1261 [05:38<13:14,  1.17it/s]
Lanes were detected
 26%|██▋       | 333/1261 [05:39<13:30,  1.14it/s]
Lanes were detected
 26%|██▋       | 334/1261 [05:40<13:46,  1.12it/s]
Lanes were detected
 27%|██▋       | 335/1261 [05:41<13:27,  1.15it/s]
Lanes were detected
 27%|██▋       | 336/1261 [05:42<13:17,  1.16it/s]
Lanes were detected
 27%|██▋       | 337/1261 [05:43<13:07,  1.17it/s]
Lanes were detected
 27%|██▋       | 338/1261 [05:43<13:02,  1.18it/s]
Lanes were detected
 27%|██▋       | 339/1261 [05:44<12:55,  1.19it/s]
Lanes were detected
 27%|██▋       | 340/1261 [05:45<12:51,  1.19it/s]
Lanes were detected
 27%|██▋       | 341/1261 [05:46<12:49,  1.20it/s]
Lanes were detected
 27%|██▋       | 342/1261 [05:47<13:14,  1.16it/s]
Lanes were detected
 27%|██▋       | 343/1261 [05:48<14:06,  1.08it/s]
Lanes were detected
 27%|██▋       | 344/1261 [05:49<14:56,  1.02it/s]
Lanes were detected
 27%|██▋       | 345/1261 [05:50<15:18,  1.00s/it]
Lanes were detected
 27%|██▋       | 346/1261 [05:51<15:31,  1.02s/it]
Lanes were detected
 28%|██▊       | 347/1261 [05:52<14:59,  1.02it/s]
Lanes were detected
 28%|██▊       | 348/1261 [05:53<14:18,  1.06it/s]
Lanes were detected
 28%|██▊       | 349/1261 [05:54<13:46,  1.10it/s]
Lanes were detected
 28%|██▊       | 350/1261 [05:54<13:27,  1.13it/s]
Lanes were detected
 28%|██▊       | 351/1261 [05:55<13:16,  1.14it/s]
Lanes were detected
 28%|██▊       | 352/1261 [05:56<12:54,  1.17it/s]
Lanes were detected
 28%|██▊       | 353/1261 [05:57<12:59,  1.17it/s]
Lanes were detected
 28%|██▊       | 354/1261 [05:58<13:02,  1.16it/s]
Lanes were detected
 28%|██▊       | 355/1261 [05:59<13:21,  1.13it/s]
Lanes were detected
 28%|██▊       | 356/1261 [06:00<14:07,  1.07it/s]
Lanes were detected
 28%|██▊       | 357/1261 [06:01<15:42,  1.04s/it]
Lanes were detected
 28%|██▊       | 358/1261 [06:02<16:12,  1.08s/it]
Lanes were detected
 28%|██▊       | 359/1261 [06:03<15:42,  1.04s/it]
Lanes were detected
 29%|██▊       | 360/1261 [06:04<15:12,  1.01s/it]
Lanes were detected
 29%|██▊       | 361/1261 [06:05<15:09,  1.01s/it]
Lanes were detected
 29%|██▊       | 362/1261 [06:06<15:11,  1.01s/it]
Lanes were detected
 29%|██▉       | 363/1261 [06:07<14:53,  1.00it/s]
Lanes were detected
 29%|██▉       | 364/1261 [06:08<14:20,  1.04it/s]
Lanes were detected
 29%|██▉       | 365/1261 [06:09<13:58,  1.07it/s]
Lanes were detected
 29%|██▉       | 366/1261 [06:10<15:04,  1.01s/it]
Lanes were detected
 29%|██▉       | 367/1261 [06:11<15:11,  1.02s/it]
Lanes were detected
 29%|██▉       | 368/1261 [06:12<15:06,  1.02s/it]
Lanes were detected
 29%|██▉       | 369/1261 [06:13<14:53,  1.00s/it]
Lanes were detected
 29%|██▉       | 370/1261 [06:14<14:25,  1.03it/s]
Lanes were detected
 29%|██▉       | 371/1261 [06:15<14:03,  1.06it/s]
Lanes were detected
 30%|██▉       | 372/1261 [06:16<13:43,  1.08it/s]
Lanes were detected
 30%|██▉       | 373/1261 [06:17<13:32,  1.09it/s]
Lanes were detected
 30%|██▉       | 374/1261 [06:18<13:29,  1.10it/s]
Lanes were detected
 30%|██▉       | 375/1261 [06:19<13:28,  1.10it/s]
Lanes were detected
 30%|██▉       | 376/1261 [06:19<13:29,  1.09it/s]
Lanes were detected
 30%|██▉       | 377/1261 [06:21<14:53,  1.01s/it]
Lanes were detected
 30%|██▉       | 378/1261 [06:22<15:37,  1.06s/it]
Lanes were detected
 30%|███       | 379/1261 [06:23<16:47,  1.14s/it]
Lanes were detected
 30%|███       | 380/1261 [06:24<17:19,  1.18s/it]
Lanes were detected
 30%|███       | 381/1261 [06:26<16:37,  1.13s/it]
Lanes were detected
 30%|███       | 382/1261 [06:26<15:52,  1.08s/it]
Lanes were detected
 30%|███       | 383/1261 [06:28<15:41,  1.07s/it]
Lanes were detected
 30%|███       | 384/1261 [06:29<15:43,  1.08s/it]
Lanes were detected
 31%|███       | 385/1261 [06:30<15:39,  1.07s/it]
Lanes were detected
 31%|███       | 386/1261 [06:31<16:11,  1.11s/it]
Lanes were detected
 31%|███       | 387/1261 [06:32<17:05,  1.17s/it]
Lanes were detected
 31%|███       | 388/1261 [06:33<16:08,  1.11s/it]
Lanes were detected
 31%|███       | 389/1261 [06:34<15:19,  1.05s/it]
Lanes were detected
 31%|███       | 390/1261 [06:35<14:57,  1.03s/it]
Lanes were detected
 31%|███       | 391/1261 [06:36<14:49,  1.02s/it]
Lanes were detected
 31%|███       | 392/1261 [06:37<14:41,  1.01s/it]
Lanes were detected
 31%|███       | 393/1261 [06:38<14:52,  1.03s/it]
Lanes were detected
 31%|███       | 394/1261 [06:39<14:30,  1.00s/it]
Lanes were detected
 31%|███▏      | 395/1261 [06:40<15:50,  1.10s/it]
Lanes were detected
 31%|███▏      | 396/1261 [06:41<15:39,  1.09s/it]
Lanes were detected
 31%|███▏      | 397/1261 [06:42<15:06,  1.05s/it]
Lanes were detected
 32%|███▏      | 398/1261 [06:44<15:49,  1.10s/it]
Lanes were detected
 32%|███▏      | 399/1261 [06:45<16:41,  1.16s/it]
Lanes were detected
 32%|███▏      | 400/1261 [06:46<16:51,  1.17s/it]
Lanes were detected
 32%|███▏      | 401/1261 [06:47<16:49,  1.17s/it]
Lanes were detected
 32%|███▏      | 402/1261 [06:48<16:24,  1.15s/it]
Lanes were detected
 32%|███▏      | 403/1261 [06:49<15:11,  1.06s/it]
Lanes were detected
 32%|███▏      | 404/1261 [06:50<14:30,  1.02s/it]
Lanes were detected
 32%|███▏      | 405/1261 [06:51<13:58,  1.02it/s]
Lanes were detected
 32%|███▏      | 406/1261 [06:52<13:33,  1.05it/s]
Lanes were detected
 32%|███▏      | 407/1261 [06:53<13:10,  1.08it/s]
Lanes were detected
 32%|███▏      | 408/1261 [06:54<12:58,  1.10it/s]
Lanes were detected
 32%|███▏      | 409/1261 [06:55<12:40,  1.12it/s]
Lanes were detected
 33%|███▎      | 410/1261 [06:55<12:30,  1.13it/s]
Lanes were detected
 33%|███▎      | 411/1261 [06:56<12:22,  1.14it/s]
Lanes were detected
 33%|███▎      | 412/1261 [06:57<12:21,  1.14it/s]
Lanes were detected
 33%|███▎      | 413/1261 [06:58<12:49,  1.10it/s]
Lanes were detected
 33%|███▎      | 414/1261 [06:59<13:12,  1.07it/s]
Lanes were detected
 33%|███▎      | 415/1261 [07:00<14:22,  1.02s/it]
Lanes were detected
 33%|███▎      | 416/1261 [07:02<15:30,  1.10s/it]
Lanes were detected
 33%|███▎      | 417/1261 [07:03<15:26,  1.10s/it]
Lanes were detected
 33%|███▎      | 418/1261 [07:04<15:23,  1.10s/it]
Lanes were detected
 33%|███▎      | 419/1261 [07:05<15:19,  1.09s/it]
Lanes were detected
 33%|███▎      | 420/1261 [07:06<15:14,  1.09s/it]
Lanes were detected
 33%|███▎      | 421/1261 [07:07<15:03,  1.08s/it]
Lanes were detected
 33%|███▎      | 422/1261 [07:08<14:59,  1.07s/it]
Lanes were detected
 34%|███▎      | 423/1261 [07:09<14:57,  1.07s/it]
Lanes were detected
 34%|███▎      | 424/1261 [07:10<14:51,  1.06s/it]
Lanes were detected
 34%|███▎      | 425/1261 [07:11<14:41,  1.05s/it]
Lanes were detected
 34%|███▍      | 426/1261 [07:12<14:40,  1.05s/it]
Lanes were detected
 34%|███▍      | 427/1261 [07:13<14:30,  1.04s/it]
Lanes were detected
 34%|███▍      | 428/1261 [07:14<14:23,  1.04s/it]
Lanes were detected
 34%|███▍      | 429/1261 [07:15<14:20,  1.03s/it]
Lanes were detected
 34%|███▍      | 430/1261 [07:16<14:18,  1.03s/it]
Lanes were detected
 34%|███▍      | 431/1261 [07:17<14:20,  1.04s/it]
Lanes were detected
 34%|███▍      | 432/1261 [07:18<14:15,  1.03s/it]
Lanes were detected
 34%|███▍      | 433/1261 [07:19<14:09,  1.03s/it]
Lanes were detected
 34%|███▍      | 434/1261 [07:20<13:59,  1.01s/it]
Lanes were detected
 34%|███▍      | 435/1261 [07:21<14:00,  1.02s/it]
Lanes were detected
 35%|███▍      | 436/1261 [07:22<13:58,  1.02s/it]
Lanes were detected
 35%|███▍      | 437/1261 [07:23<13:54,  1.01s/it]
Lanes were detected
 35%|███▍      | 438/1261 [07:24<13:56,  1.02s/it]
Lanes were detected
 35%|███▍      | 439/1261 [07:26<13:58,  1.02s/it]
Lanes were detected
 35%|███▍      | 440/1261 [07:27<13:57,  1.02s/it]
Lanes were detected
 35%|███▍      | 441/1261 [07:28<14:03,  1.03s/it]
Lanes were detected
 35%|███▌      | 442/1261 [07:29<14:01,  1.03s/it]
Lanes were detected
 35%|███▌      | 443/1261 [07:30<14:01,  1.03s/it]
Lanes were detected
 35%|███▌      | 444/1261 [07:31<14:00,  1.03s/it]
Lanes were detected
 35%|███▌      | 445/1261 [07:32<13:49,  1.02s/it]
Lanes were detected
 35%|███▌      | 446/1261 [07:33<13:49,  1.02s/it]
Lanes were detected
 35%|███▌      | 447/1261 [07:34<13:23,  1.01it/s]
Lanes were detected
 36%|███▌      | 448/1261 [07:34<12:50,  1.06it/s]
Lanes were detected
 36%|███▌      | 449/1261 [07:35<12:35,  1.08it/s]
Lanes were detected
 36%|███▌      | 450/1261 [07:36<12:16,  1.10it/s]
Lanes were detected
 36%|███▌      | 451/1261 [07:37<12:23,  1.09it/s]
Lanes were detected
 36%|███▌      | 452/1261 [07:38<12:16,  1.10it/s]
Lanes were detected
 36%|███▌      | 453/1261 [07:39<12:11,  1.10it/s]
Lanes were detected
 36%|███▌      | 454/1261 [07:40<12:02,  1.12it/s]
Lanes were detected
 36%|███▌      | 455/1261 [07:41<11:59,  1.12it/s]
Lanes were detected
 36%|███▌      | 456/1261 [07:42<11:54,  1.13it/s]
Lanes were detected
 36%|███▌      | 457/1261 [07:42<11:56,  1.12it/s]
Lanes were detected
 36%|███▋      | 458/1261 [07:43<11:51,  1.13it/s]
Lanes were detected
 36%|███▋      | 459/1261 [07:44<11:46,  1.14it/s]
Lanes were detected
 36%|███▋      | 460/1261 [07:45<11:44,  1.14it/s]
Lanes were detected
 37%|███▋      | 461/1261 [07:46<11:43,  1.14it/s]
Lanes were detected
 37%|███▋      | 462/1261 [07:47<12:15,  1.09it/s]
Lanes were detected
 37%|███▋      | 463/1261 [07:48<11:51,  1.12it/s]
Lanes were detected
 37%|███▋      | 464/1261 [07:49<13:03,  1.02it/s]
Lanes were detected
 37%|███▋      | 465/1261 [07:50<13:46,  1.04s/it]
Lanes were detected
 37%|███▋      | 466/1261 [07:51<13:18,  1.00s/it]
Lanes were detected
 37%|███▋      | 467/1261 [07:52<13:21,  1.01s/it]
Lanes were detected
 37%|███▋      | 468/1261 [07:53<13:47,  1.04s/it]
Lanes were detected
 37%|███▋      | 469/1261 [07:54<13:46,  1.04s/it]
Lanes were detected
 37%|███▋      | 470/1261 [07:55<13:32,  1.03s/it]
Lanes were detected
 37%|███▋      | 471/1261 [07:56<13:29,  1.02s/it]
Lanes were detected
 37%|███▋      | 472/1261 [07:57<12:57,  1.01it/s]
Lanes were detected
 38%|███▊      | 473/1261 [07:58<12:44,  1.03it/s]
Lanes were detected
 38%|███▊      | 474/1261 [07:59<12:24,  1.06it/s]
Lanes were detected
 38%|███▊      | 475/1261 [08:00<12:10,  1.08it/s]
Lanes were detected
 38%|███▊      | 476/1261 [08:01<12:10,  1.07it/s]
Lanes were detected
 38%|███▊      | 477/1261 [08:02<12:01,  1.09it/s]
Lanes were detected
 38%|███▊      | 478/1261 [08:03<11:36,  1.12it/s]
Lanes were detected
 38%|███▊      | 479/1261 [08:03<11:17,  1.15it/s]
Lanes were detected
 38%|███▊      | 480/1261 [08:04<11:06,  1.17it/s]
Lanes were detected
 38%|███▊      | 481/1261 [08:05<11:03,  1.18it/s]
Lanes were detected
 38%|███▊      | 482/1261 [08:06<10:57,  1.19it/s]
Lanes were detected
 38%|███▊      | 483/1261 [08:07<11:06,  1.17it/s]
Lanes were detected
 38%|███▊      | 484/1261 [08:08<11:20,  1.14it/s]
Lanes were detected
 38%|███▊      | 485/1261 [08:09<11:31,  1.12it/s]
Lanes were detected
 39%|███▊      | 486/1261 [08:10<11:52,  1.09it/s]
Lanes were detected
 39%|███▊      | 487/1261 [08:11<12:24,  1.04it/s]
Lanes were detected
 39%|███▊      | 488/1261 [08:12<12:07,  1.06it/s]
Lanes were detected
 39%|███▉      | 489/1261 [08:12<11:57,  1.08it/s]
Lanes were detected
 39%|███▉      | 490/1261 [08:13<11:46,  1.09it/s]
Lanes were detected
 39%|███▉      | 491/1261 [08:14<11:41,  1.10it/s]
Lanes were detected
 39%|███▉      | 492/1261 [08:15<11:27,  1.12it/s]
Lanes were detected
 39%|███▉      | 493/1261 [08:16<11:08,  1.15it/s]
Lanes were detected
 39%|███▉      | 494/1261 [08:17<10:56,  1.17it/s]
Lanes were detected
 39%|███▉      | 495/1261 [08:18<10:50,  1.18it/s]
Lanes were detected
 39%|███▉      | 496/1261 [08:18<10:45,  1.18it/s]
Lanes were detected
 39%|███▉      | 497/1261 [08:19<10:40,  1.19it/s]
Lanes were detected
 39%|███▉      | 498/1261 [08:20<10:37,  1.20it/s]
Lanes were detected
 40%|███▉      | 499/1261 [08:21<10:41,  1.19it/s]
Lanes were detected
 40%|███▉      | 500/1261 [08:22<10:39,  1.19it/s]
Lanes were detected
 40%|███▉      | 501/1261 [08:23<10:40,  1.19it/s]
Lanes were detected
 40%|███▉      | 502/1261 [08:23<10:37,  1.19it/s]
Lanes were detected
 40%|███▉      | 503/1261 [08:24<10:38,  1.19it/s]
Lanes were detected
 40%|███▉      | 504/1261 [08:25<10:35,  1.19it/s]
Lanes were detected
 40%|████      | 505/1261 [08:26<10:35,  1.19it/s]
Lanes were detected
 40%|████      | 506/1261 [08:27<10:37,  1.18it/s]
Lanes were detected
 40%|████      | 507/1261 [08:28<10:37,  1.18it/s]
Lanes were detected
 40%|████      | 508/1261 [08:28<10:37,  1.18it/s]
Lanes were detected
 40%|████      | 509/1261 [08:29<10:37,  1.18it/s]
Lanes were detected
 40%|████      | 510/1261 [08:30<10:33,  1.19it/s]
Lanes were detected
 41%|████      | 511/1261 [08:31<10:36,  1.18it/s]
Lanes were detected
 41%|████      | 512/1261 [08:32<10:34,  1.18it/s]
Lanes were detected
 41%|████      | 513/1261 [08:33<10:33,  1.18it/s]
Lanes were detected
 41%|████      | 514/1261 [08:34<10:32,  1.18it/s]
Lanes were detected
 41%|████      | 515/1261 [08:34<10:30,  1.18it/s]
Lanes were detected
 41%|████      | 516/1261 [08:35<10:29,  1.18it/s]
Lanes were detected
 41%|████      | 517/1261 [08:36<10:28,  1.18it/s]
Lanes were detected
 41%|████      | 518/1261 [08:37<10:28,  1.18it/s]
Lanes were detected
 41%|████      | 519/1261 [08:38<10:28,  1.18it/s]
Lanes were detected
 41%|████      | 520/1261 [08:39<10:28,  1.18it/s]
Lanes were detected
 41%|████▏     | 521/1261 [08:39<10:27,  1.18it/s]
Lanes were detected
 41%|████▏     | 522/1261 [08:40<10:24,  1.18it/s]
Lanes were detected
 41%|████▏     | 523/1261 [08:41<10:23,  1.18it/s]
Lanes were detected
 42%|████▏     | 524/1261 [08:42<10:19,  1.19it/s]
Lanes were detected
 42%|████▏     | 525/1261 [08:43<10:18,  1.19it/s]
Lanes were detected
 42%|████▏     | 526/1261 [08:44<10:14,  1.20it/s]
Lanes were detected
 42%|████▏     | 527/1261 [08:45<10:16,  1.19it/s]
Lanes were detected
 42%|████▏     | 528/1261 [08:45<10:16,  1.19it/s]
Lanes were detected
 42%|████▏     | 529/1261 [08:46<10:14,  1.19it/s]
Lanes were detected
 42%|████▏     | 530/1261 [08:47<10:19,  1.18it/s]
Lanes were detected
 42%|████▏     | 531/1261 [08:48<10:52,  1.12it/s]
Lanes were detected
 42%|████▏     | 532/1261 [08:49<11:07,  1.09it/s]
Lanes were detected
 42%|████▏     | 533/1261 [08:50<11:13,  1.08it/s]
Lanes were detected
 42%|████▏     | 534/1261 [08:51<11:00,  1.10it/s]
Lanes were detected
 42%|████▏     | 535/1261 [08:52<10:50,  1.12it/s]
Lanes were detected
 43%|████▎     | 536/1261 [08:53<10:39,  1.13it/s]
Lanes were detected
 43%|████▎     | 537/1261 [08:53<10:33,  1.14it/s]
Lanes were detected
 43%|████▎     | 538/1261 [08:54<10:37,  1.13it/s]
Lanes were detected
 43%|████▎     | 539/1261 [08:55<10:58,  1.10it/s]
Lanes were detected
 43%|████▎     | 540/1261 [08:56<10:45,  1.12it/s]
Lanes were detected
 43%|████▎     | 541/1261 [08:57<10:34,  1.13it/s]
Lanes were detected
 43%|████▎     | 542/1261 [08:58<10:29,  1.14it/s]
Lanes were detected
 43%|████▎     | 543/1261 [08:59<10:40,  1.12it/s]
Lanes were detected
 43%|████▎     | 544/1261 [09:00<11:01,  1.08it/s]
Lanes were detected
 43%|████▎     | 545/1261 [09:01<11:00,  1.08it/s]
Lanes weren't detected
 43%|████▎     | 546/1261 [09:02<10:56,  1.09it/s]
Lanes weren't detected
 43%|████▎     | 547/1261 [09:02<10:43,  1.11it/s]
Lanes weren't detected
 43%|████▎     | 548/1261 [09:03<10:29,  1.13it/s]
Lanes weren't detected
 44%|████▎     | 549/1261 [09:04<10:20,  1.15it/s]
Lanes weren't detected
 44%|████▎     | 550/1261 [09:05<10:15,  1.16it/s]
Lanes were detected
 44%|████▎     | 551/1261 [09:06<10:07,  1.17it/s]
Lanes were detected
 44%|████▍     | 552/1261 [09:07<10:02,  1.18it/s]
Lanes were detected
 44%|████▍     | 553/1261 [09:08<09:57,  1.19it/s]
Lanes were detected
 44%|████▍     | 554/1261 [09:08<10:06,  1.16it/s]
Lanes weren't detected
 44%|████▍     | 555/1261 [09:09<10:13,  1.15it/s]
Lanes weren't detected
 44%|████▍     | 556/1261 [09:10<10:09,  1.16it/s]
Lanes were detected
 44%|████▍     | 557/1261 [09:11<10:06,  1.16it/s]
Lanes were detected
 44%|████▍     | 558/1261 [09:12<10:03,  1.17it/s]
Lanes weren't detected
 44%|████▍     | 559/1261 [09:13<09:58,  1.17it/s]
Lanes weren't detected
 44%|████▍     | 560/1261 [09:14<09:58,  1.17it/s]
Lanes weren't detected
 44%|████▍     | 561/1261 [09:14<09:52,  1.18it/s]
Lanes weren't detected
 45%|████▍     | 562/1261 [09:15<09:54,  1.18it/s]
Lanes weren't detected
 45%|████▍     | 563/1261 [09:16<09:49,  1.18it/s]
Lanes were detected
 45%|████▍     | 564/1261 [09:17<10:13,  1.14it/s]
Lanes were detected
 45%|████▍     | 565/1261 [09:18<10:14,  1.13it/s]
Lanes were detected
 45%|████▍     | 566/1261 [09:19<09:59,  1.16it/s]
Lanes were detected
 45%|████▍     | 567/1261 [09:20<09:44,  1.19it/s]
Lanes were detected
 45%|████▌     | 568/1261 [09:20<09:39,  1.20it/s]
Lanes were detected
 45%|████▌     | 569/1261 [09:21<09:27,  1.22it/s]
Lanes weren't detected
 45%|████▌     | 570/1261 [09:22<09:24,  1.22it/s]
Lanes were detected
 45%|████▌     | 571/1261 [09:23<09:21,  1.23it/s]
Lanes were detected
 45%|████▌     | 572/1261 [09:24<09:18,  1.23it/s]
Lanes were detected
 45%|████▌     | 573/1261 [09:24<09:13,  1.24it/s]
Lanes were detected
 46%|████▌     | 574/1261 [09:25<09:10,  1.25it/s]
Lanes were detected
 46%|████▌     | 575/1261 [09:26<09:10,  1.25it/s]
Lanes were detected
 46%|████▌     | 576/1261 [09:27<09:10,  1.24it/s]
Lanes were detected
 46%|████▌     | 577/1261 [09:28<09:20,  1.22it/s]
Lanes were detected
 46%|████▌     | 578/1261 [09:28<09:24,  1.21it/s]
Lanes were detected
 46%|████▌     | 579/1261 [09:29<09:27,  1.20it/s]
Lanes were detected
 46%|████▌     | 580/1261 [09:30<09:24,  1.21it/s]
Lanes were detected
 46%|████▌     | 581/1261 [09:31<09:24,  1.21it/s]
Lanes were detected
 46%|████▌     | 582/1261 [09:32<09:25,  1.20it/s]
Lanes were detected
 46%|████▌     | 583/1261 [09:33<09:20,  1.21it/s]
Lanes were detected
 46%|████▋     | 584/1261 [09:33<09:16,  1.22it/s]
Lanes were detected
 46%|████▋     | 585/1261 [09:34<09:33,  1.18it/s]
Lanes were detected
 46%|████▋     | 586/1261 [09:35<09:29,  1.19it/s]
Lanes were detected
 47%|████▋     | 587/1261 [09:36<09:20,  1.20it/s]
Lanes were detected
 47%|████▋     | 588/1261 [09:37<09:10,  1.22it/s]
Lanes were detected
 47%|████▋     | 589/1261 [09:38<09:13,  1.21it/s]
Lanes were detected
 47%|████▋     | 590/1261 [09:38<09:17,  1.20it/s]
Lanes were detected
 47%|████▋     | 591/1261 [09:39<09:26,  1.18it/s]
Lanes were detected
 47%|████▋     | 592/1261 [09:40<09:44,  1.14it/s]
Lanes were detected
 47%|████▋     | 593/1261 [09:41<09:40,  1.15it/s]
Lanes were detected
 47%|████▋     | 594/1261 [09:42<09:29,  1.17it/s]
Lanes were detected
 47%|████▋     | 595/1261 [09:43<09:45,  1.14it/s]
Lanes were detected
 47%|████▋     | 596/1261 [09:44<09:40,  1.15it/s]
Lanes were detected
 47%|████▋     | 597/1261 [09:45<09:36,  1.15it/s]
Lanes were detected
 47%|████▋     | 598/1261 [09:45<09:25,  1.17it/s]
Lanes were detected
 48%|████▊     | 599/1261 [09:46<09:18,  1.19it/s]
Lanes were detected
 48%|████▊     | 600/1261 [09:47<09:19,  1.18it/s]
Lanes were detected
 48%|████▊     | 601/1261 [09:48<09:22,  1.17it/s]
Lanes were detected
 48%|████▊     | 602/1261 [09:49<09:23,  1.17it/s]
Lanes were detected
 48%|████▊     | 603/1261 [09:50<09:33,  1.15it/s]
Lanes were detected
 48%|████▊     | 604/1261 [09:51<09:36,  1.14it/s]
Lanes were detected
 48%|████▊     | 605/1261 [09:52<09:59,  1.09it/s]
Lanes were detected
 48%|████▊     | 606/1261 [09:53<09:58,  1.09it/s]
Lanes were detected
 48%|████▊     | 607/1261 [09:53<09:54,  1.10it/s]
Lanes were detected
 48%|████▊     | 608/1261 [09:54<09:40,  1.13it/s]
Lanes were detected
 48%|████▊     | 609/1261 [09:55<09:51,  1.10it/s]
Lanes were detected
 48%|████▊     | 610/1261 [09:56<09:45,  1.11it/s]
Lanes were detected
 48%|████▊     | 611/1261 [09:57<09:42,  1.12it/s]
Lanes were detected
 49%|████▊     | 612/1261 [09:58<09:31,  1.14it/s]
Lanes were detected
 49%|████▊     | 613/1261 [09:59<09:35,  1.13it/s]
Lanes were detected
 49%|████▊     | 614/1261 [10:00<09:31,  1.13it/s]
Lanes were detected
 49%|████▉     | 615/1261 [10:01<09:45,  1.10it/s]
Lanes were detected
 49%|████▉     | 616/1261 [10:02<10:26,  1.03it/s]
Lanes were detected
 49%|████▉     | 617/1261 [10:03<10:05,  1.06it/s]
Lanes were detected
 49%|████▉     | 618/1261 [10:03<09:52,  1.09it/s]
Lanes were detected
 49%|████▉     | 619/1261 [10:04<09:43,  1.10it/s]
Lanes were detected
 49%|████▉     | 620/1261 [10:05<09:33,  1.12it/s]
Lanes were detected
 49%|████▉     | 621/1261 [10:06<09:36,  1.11it/s]
Lanes were detected
 49%|████▉     | 622/1261 [10:07<09:33,  1.12it/s]
Lanes were detected
 49%|████▉     | 623/1261 [10:08<09:40,  1.10it/s]
Lanes were detected
 49%|████▉     | 624/1261 [10:09<09:35,  1.11it/s]
Lanes were detected
 50%|████▉     | 625/1261 [10:10<10:06,  1.05it/s]
Lanes were detected
 50%|████▉     | 626/1261 [10:11<10:51,  1.03s/it]
Lanes were detected
 50%|████▉     | 627/1261 [10:12<10:32,  1.00it/s]
Lanes were detected
 50%|████▉     | 628/1261 [10:13<10:18,  1.02it/s]
Lanes were detected
 50%|████▉     | 629/1261 [10:14<09:57,  1.06it/s]
Lanes were detected
 50%|████▉     | 630/1261 [10:15<09:39,  1.09it/s]
Lanes were detected
 50%|█████     | 631/1261 [10:16<09:24,  1.12it/s]
Lanes were detected
 50%|█████     | 632/1261 [10:16<09:24,  1.11it/s]
Lanes were detected
 50%|█████     | 633/1261 [10:17<09:27,  1.11it/s]
Lanes were detected
 50%|█████     | 634/1261 [10:18<09:31,  1.10it/s]
Lanes were detected
 50%|█████     | 635/1261 [10:19<10:32,  1.01s/it]
Lanes were detected
 50%|█████     | 636/1261 [10:21<11:11,  1.07s/it]
Lanes were detected
 51%|█████     | 637/1261 [10:22<10:36,  1.02s/it]
Lanes were detected
 51%|█████     | 638/1261 [10:23<10:16,  1.01it/s]
Lanes were detected
 51%|█████     | 639/1261 [10:23<09:57,  1.04it/s]
Lanes were detected
 51%|█████     | 640/1261 [10:24<09:54,  1.04it/s]
Lanes were detected
 51%|█████     | 641/1261 [10:25<09:41,  1.07it/s]
Lanes were detected
 51%|█████     | 642/1261 [10:26<09:29,  1.09it/s]
Lanes were detected
 51%|█████     | 643/1261 [10:27<09:09,  1.12it/s]
Lanes were detected
 51%|█████     | 644/1261 [10:28<09:18,  1.10it/s]
Lanes were detected
 51%|█████     | 645/1261 [10:29<09:31,  1.08it/s]
Lanes were detected
 51%|█████     | 646/1261 [10:30<10:07,  1.01it/s]
Lanes were detected
 51%|█████▏    | 647/1261 [10:31<10:12,  1.00it/s]
Lanes were detected
 51%|█████▏    | 648/1261 [10:32<10:48,  1.06s/it]
Lanes were detected
 51%|█████▏    | 649/1261 [10:34<11:42,  1.15s/it]
Lanes were detected
 52%|█████▏    | 650/1261 [10:34<10:51,  1.07s/it]
Lanes were detected
 52%|█████▏    | 651/1261 [10:35<10:34,  1.04s/it]
Lanes were detected
 52%|█████▏    | 652/1261 [10:36<10:22,  1.02s/it]
Lanes were detected
 52%|█████▏    | 653/1261 [10:37<10:11,  1.01s/it]
Lanes were detected
 52%|█████▏    | 654/1261 [10:38<10:13,  1.01s/it]
Lanes were detected
 52%|█████▏    | 655/1261 [10:39<10:00,  1.01it/s]
Lanes were detected
 52%|█████▏    | 656/1261 [10:40<10:26,  1.04s/it]
Lanes were detected
 52%|█████▏    | 657/1261 [10:41<09:46,  1.03it/s]
Lanes were detected
 52%|█████▏    | 658/1261 [10:42<09:15,  1.09it/s]
Lanes were detected
 52%|█████▏    | 659/1261 [10:43<09:02,  1.11it/s]
Lanes were detected
 52%|█████▏    | 660/1261 [10:44<08:57,  1.12it/s]
Lanes were detected
 52%|█████▏    | 661/1261 [10:45<08:52,  1.13it/s]
Lanes were detected
 52%|█████▏    | 662/1261 [10:46<08:39,  1.15it/s]
Lanes were detected
 53%|█████▎    | 663/1261 [10:46<08:35,  1.16it/s]
Lanes were detected
 53%|█████▎    | 664/1261 [10:47<08:26,  1.18it/s]
Lanes were detected
 53%|█████▎    | 665/1261 [10:48<08:19,  1.19it/s]
Lanes were detected
 53%|█████▎    | 666/1261 [10:49<08:20,  1.19it/s]
Lanes were detected
 53%|█████▎    | 667/1261 [10:50<08:16,  1.20it/s]
Lanes were detected
 53%|█████▎    | 668/1261 [10:51<08:30,  1.16it/s]
Lanes were detected
 53%|█████▎    | 669/1261 [10:52<08:36,  1.15it/s]
Lanes were detected
 53%|█████▎    | 670/1261 [10:53<09:01,  1.09it/s]
Lanes were detected
 53%|█████▎    | 671/1261 [10:53<08:48,  1.12it/s]
Lanes were detected
 53%|█████▎    | 672/1261 [10:54<08:57,  1.10it/s]
Lanes were detected
 53%|█████▎    | 673/1261 [10:55<09:12,  1.06it/s]
Lanes were detected
 53%|█████▎    | 674/1261 [10:56<09:00,  1.09it/s]
Lanes were detected
 54%|█████▎    | 675/1261 [10:57<08:53,  1.10it/s]
Lanes were detected
 54%|█████▎    | 676/1261 [10:58<08:46,  1.11it/s]
Lanes were detected
 54%|█████▎    | 677/1261 [10:59<08:40,  1.12it/s]
Lanes were detected
 54%|█████▍    | 678/1261 [11:00<08:25,  1.15it/s]
Lanes were detected
 54%|█████▍    | 679/1261 [11:01<08:40,  1.12it/s]
Lanes were detected
 54%|█████▍    | 680/1261 [11:02<08:48,  1.10it/s]
Lanes were detected
 54%|█████▍    | 681/1261 [11:02<08:31,  1.13it/s]
Lanes were detected
 54%|█████▍    | 682/1261 [11:03<08:17,  1.16it/s]
Lanes were detected
 54%|█████▍    | 683/1261 [11:04<08:11,  1.18it/s]
Lanes were detected
 54%|█████▍    | 684/1261 [11:05<08:02,  1.20it/s]
Lanes were detected
 54%|█████▍    | 685/1261 [11:06<07:57,  1.21it/s]
Lanes were detected
 54%|█████▍    | 686/1261 [11:06<07:57,  1.20it/s]
Lanes were detected
 54%|█████▍    | 687/1261 [11:07<07:47,  1.23it/s]
Lanes were detected
 55%|█████▍    | 688/1261 [11:08<07:43,  1.23it/s]
Lanes were detected
 55%|█████▍    | 689/1261 [11:09<07:45,  1.23it/s]
Lanes were detected
 55%|█████▍    | 690/1261 [11:10<07:38,  1.25it/s]
Lanes were detected
 55%|█████▍    | 691/1261 [11:10<07:38,  1.24it/s]
Lanes were detected
 55%|█████▍    | 692/1261 [11:11<07:36,  1.25it/s]
Lanes were detected
 55%|█████▍    | 693/1261 [11:12<07:31,  1.26it/s]
Lanes were detected
 55%|█████▌    | 694/1261 [11:13<07:31,  1.26it/s]
Lanes were detected
 55%|█████▌    | 695/1261 [11:14<07:48,  1.21it/s]
Lanes were detected
 55%|█████▌    | 696/1261 [11:15<07:44,  1.22it/s]
Lanes were detected
 55%|█████▌    | 697/1261 [11:15<07:36,  1.24it/s]
Lanes were detected
 55%|█████▌    | 698/1261 [11:16<07:32,  1.24it/s]
Lanes were detected
 55%|█████▌    | 699/1261 [11:17<07:26,  1.26it/s]
Lanes were detected
 56%|█████▌    | 700/1261 [11:18<07:24,  1.26it/s]
Lanes were detected
 56%|█████▌    | 701/1261 [11:18<07:22,  1.27it/s]
Lanes were detected
 56%|█████▌    | 702/1261 [11:19<07:22,  1.26it/s]
Lanes were detected
 56%|█████▌    | 703/1261 [11:20<07:22,  1.26it/s]
Lanes were detected
 56%|█████▌    | 704/1261 [11:21<07:23,  1.25it/s]
Lanes were detected
 56%|█████▌    | 705/1261 [11:22<07:27,  1.24it/s]
Lanes were detected
 56%|█████▌    | 706/1261 [11:23<07:35,  1.22it/s]
Lanes were detected
 56%|█████▌    | 707/1261 [11:23<07:32,  1.23it/s]
Lanes were detected
 56%|█████▌    | 708/1261 [11:24<07:33,  1.22it/s]
Lanes were detected
 56%|█████▌    | 709/1261 [11:25<07:29,  1.23it/s]
Lanes were detected
 56%|█████▋    | 710/1261 [11:26<07:28,  1.23it/s]
Lanes were detected
 56%|█████▋    | 711/1261 [11:27<07:25,  1.23it/s]
Lanes were detected
 56%|█████▋    | 712/1261 [11:27<07:25,  1.23it/s]
Lanes were detected
 57%|█████▋    | 713/1261 [11:28<07:24,  1.23it/s]
Lanes were detected
 57%|█████▋    | 714/1261 [11:29<07:24,  1.23it/s]
Lanes were detected
 57%|█████▋    | 715/1261 [11:30<07:22,  1.23it/s]
Lanes were detected
 57%|█████▋    | 716/1261 [11:31<07:22,  1.23it/s]
Lanes were detected
 57%|█████▋    | 717/1261 [11:31<07:20,  1.24it/s]
Lanes were detected
 57%|█████▋    | 718/1261 [11:32<07:17,  1.24it/s]
Lanes were detected
 57%|█████▋    | 719/1261 [11:33<07:18,  1.24it/s]
Lanes were detected
 57%|█████▋    | 720/1261 [11:34<07:43,  1.17it/s]
Lanes were detected
 57%|█████▋    | 721/1261 [11:35<07:45,  1.16it/s]
Lanes were detected
 57%|█████▋    | 722/1261 [11:36<07:44,  1.16it/s]
Lanes were detected
 57%|█████▋    | 723/1261 [11:37<07:38,  1.17it/s]
Lanes were detected
 57%|█████▋    | 724/1261 [11:37<07:33,  1.19it/s]
Lanes were detected
 57%|█████▋    | 725/1261 [11:38<07:37,  1.17it/s]
Lanes were detected
 58%|█████▊    | 726/1261 [11:39<07:36,  1.17it/s]
Lanes were detected
 58%|█████▊    | 727/1261 [11:40<07:32,  1.18it/s]
Lanes were detected
 58%|█████▊    | 728/1261 [11:41<07:27,  1.19it/s]
Lanes were detected
 58%|█████▊    | 729/1261 [11:42<07:28,  1.19it/s]
Lanes were detected
 58%|█████▊    | 730/1261 [11:42<07:27,  1.19it/s]
Lanes were detected
 58%|█████▊    | 731/1261 [11:43<07:28,  1.18it/s]
Lanes were detected
 58%|█████▊    | 732/1261 [11:44<07:31,  1.17it/s]
Lanes were detected
 58%|█████▊    | 733/1261 [11:45<07:41,  1.14it/s]
Lanes were detected
 58%|█████▊    | 734/1261 [11:46<07:44,  1.13it/s]
Lanes were detected
 58%|█████▊    | 735/1261 [11:47<07:49,  1.12it/s]
Lanes were detected
 58%|█████▊    | 736/1261 [11:48<07:39,  1.14it/s]
Lanes were detected
 58%|█████▊    | 737/1261 [11:49<07:38,  1.14it/s]
Lanes were detected
 59%|█████▊    | 738/1261 [11:50<07:39,  1.14it/s]
Lanes were detected
 59%|█████▊    | 739/1261 [11:50<07:32,  1.15it/s]
Lanes were detected
 59%|█████▊    | 740/1261 [11:51<07:35,  1.14it/s]
Lanes were detected
 59%|█████▉    | 741/1261 [11:52<07:29,  1.16it/s]
Lanes were detected
 59%|█████▉    | 742/1261 [11:53<07:28,  1.16it/s]
Lanes were detected
 59%|█████▉    | 743/1261 [11:54<07:32,  1.15it/s]
Lanes were detected
 59%|█████▉    | 744/1261 [11:55<07:41,  1.12it/s]
Lanes were detected
 59%|█████▉    | 745/1261 [11:56<07:53,  1.09it/s]
Lanes were detected
 59%|█████▉    | 746/1261 [11:57<07:52,  1.09it/s]
Lanes were detected
 59%|█████▉    | 747/1261 [11:58<07:56,  1.08it/s]
Lanes were detected
 59%|█████▉    | 748/1261 [11:59<07:48,  1.10it/s]
Lanes were detected
 59%|█████▉    | 749/1261 [11:59<07:49,  1.09it/s]
Lanes were detected
 59%|█████▉    | 750/1261 [12:00<07:48,  1.09it/s]
Lanes were detected
 60%|█████▉    | 751/1261 [12:01<07:57,  1.07it/s]
Lanes were detected
 60%|█████▉    | 752/1261 [12:02<07:41,  1.10it/s]
Lanes were detected
 60%|█████▉    | 753/1261 [12:03<07:28,  1.13it/s]
Lanes were detected
 60%|█████▉    | 754/1261 [12:04<07:17,  1.16it/s]
Lanes were detected
 60%|█████▉    | 755/1261 [12:05<07:14,  1.16it/s]
Lanes were detected
 60%|█████▉    | 756/1261 [12:06<07:10,  1.17it/s]
Lanes were detected
 60%|██████    | 757/1261 [12:06<07:03,  1.19it/s]
Lanes were detected
 60%|██████    | 758/1261 [12:07<07:01,  1.19it/s]
Lanes were detected
 60%|██████    | 759/1261 [12:08<07:00,  1.19it/s]
Lanes were detected
 60%|██████    | 760/1261 [12:09<06:57,  1.20it/s]
Lanes were detected
 60%|██████    | 761/1261 [12:10<07:03,  1.18it/s]
Lanes were detected
 60%|██████    | 762/1261 [12:11<07:09,  1.16it/s]
Lanes were detected
 61%|██████    | 763/1261 [12:11<07:13,  1.15it/s]
Lanes were detected
 61%|██████    | 764/1261 [12:12<07:13,  1.15it/s]
Lanes were detected
 61%|██████    | 765/1261 [12:13<07:21,  1.12it/s]
Lanes were detected
 61%|██████    | 766/1261 [12:14<07:20,  1.12it/s]
Lanes were detected
 61%|██████    | 767/1261 [12:15<07:13,  1.14it/s]
Lanes were detected
 61%|██████    | 768/1261 [12:16<07:12,  1.14it/s]
Lanes were detected
 61%|██████    | 769/1261 [12:17<07:08,  1.15it/s]
Lanes were detected
 61%|██████    | 770/1261 [12:18<07:02,  1.16it/s]
Lanes were detected
 61%|██████    | 771/1261 [12:19<07:11,  1.14it/s]
Lanes were detected
 61%|██████    | 772/1261 [12:19<07:13,  1.13it/s]
Lanes were detected
 61%|██████▏   | 773/1261 [12:20<07:17,  1.11it/s]
Lanes were detected
 61%|██████▏   | 774/1261 [12:21<07:07,  1.14it/s]
Lanes were detected
 61%|██████▏   | 775/1261 [12:22<07:03,  1.15it/s]
Lanes were detected
 62%|██████▏   | 776/1261 [12:23<07:02,  1.15it/s]
Lanes were detected
 62%|██████▏   | 777/1261 [12:24<07:05,  1.14it/s]
Lanes were detected
 62%|██████▏   | 778/1261 [12:25<06:58,  1.16it/s]
Lanes were detected
 62%|██████▏   | 779/1261 [12:26<07:09,  1.12it/s]
Lanes were detected
 62%|██████▏   | 780/1261 [12:26<07:02,  1.14it/s]
Lanes were detected
 62%|██████▏   | 781/1261 [12:27<07:09,  1.12it/s]
Lanes were detected
 62%|██████▏   | 782/1261 [12:28<07:16,  1.10it/s]
Lanes were detected
 62%|██████▏   | 783/1261 [12:29<07:10,  1.11it/s]
Lanes were detected
 62%|██████▏   | 784/1261 [12:30<07:09,  1.11it/s]
Lanes were detected
 62%|██████▏   | 785/1261 [12:31<07:00,  1.13it/s]
Lanes were detected
 62%|██████▏   | 786/1261 [12:32<06:54,  1.15it/s]
Lanes were detected
 62%|██████▏   | 787/1261 [12:33<06:44,  1.17it/s]
Lanes were detected
 62%|██████▏   | 788/1261 [12:33<06:38,  1.19it/s]
Lanes were detected
 63%|██████▎   | 789/1261 [12:34<06:35,  1.19it/s]
Lanes were detected
 63%|██████▎   | 790/1261 [12:35<06:31,  1.20it/s]
Lanes were detected
 63%|██████▎   | 791/1261 [12:36<06:46,  1.16it/s]
Lanes were detected
 63%|██████▎   | 792/1261 [12:37<06:43,  1.16it/s]
Lanes were detected
 63%|██████▎   | 793/1261 [12:38<06:43,  1.16it/s]
Lanes were detected
 63%|██████▎   | 794/1261 [12:39<06:35,  1.18it/s]
Lanes were detected
 63%|██████▎   | 795/1261 [12:39<06:28,  1.20it/s]
Lanes were detected
 63%|██████▎   | 796/1261 [12:40<06:33,  1.18it/s]
Lanes were detected
 63%|██████▎   | 797/1261 [12:41<06:31,  1.18it/s]
Lanes were detected
 63%|██████▎   | 798/1261 [12:42<06:46,  1.14it/s]
Lanes were detected
 63%|██████▎   | 799/1261 [12:43<07:16,  1.06it/s]
Lanes were detected
 63%|██████▎   | 800/1261 [12:45<08:26,  1.10s/it]
Lanes were detected
 64%|██████▎   | 801/1261 [12:46<08:34,  1.12s/it]
Lanes were detected
 64%|██████▎   | 802/1261 [12:47<08:34,  1.12s/it]
Lanes were detected
 64%|██████▎   | 803/1261 [12:48<08:23,  1.10s/it]
Lanes were detected
 64%|██████▍   | 804/1261 [12:49<08:38,  1.13s/it]
Lanes were detected
 64%|██████▍   | 805/1261 [12:50<08:30,  1.12s/it]
Lanes were detected
 64%|██████▍   | 806/1261 [12:51<08:06,  1.07s/it]
Lanes were detected
 64%|██████▍   | 807/1261 [12:52<07:45,  1.03s/it]
Lanes were detected
 64%|██████▍   | 808/1261 [12:53<07:25,  1.02it/s]
Lanes were detected
 64%|██████▍   | 809/1261 [12:54<07:07,  1.06it/s]
Lanes were detected
 64%|██████▍   | 810/1261 [12:55<06:55,  1.09it/s]
Lanes were detected
 64%|██████▍   | 811/1261 [12:56<06:48,  1.10it/s]
Lanes were detected
 64%|██████▍   | 812/1261 [12:56<06:45,  1.11it/s]
Lanes were detected
 64%|██████▍   | 813/1261 [12:57<06:41,  1.12it/s]
Lanes were detected
 65%|██████▍   | 814/1261 [12:58<06:32,  1.14it/s]
Lanes were detected
 65%|██████▍   | 815/1261 [12:59<06:29,  1.14it/s]
Lanes were detected
 65%|██████▍   | 816/1261 [13:00<06:27,  1.15it/s]
Lanes were detected
 65%|██████▍   | 817/1261 [13:01<06:24,  1.15it/s]
Lanes were detected
 65%|██████▍   | 818/1261 [13:02<06:22,  1.16it/s]
Lanes were detected
 65%|██████▍   | 819/1261 [13:02<06:20,  1.16it/s]
Lanes were detected
 65%|██████▌   | 820/1261 [13:03<06:19,  1.16it/s]
Lanes were detected
 65%|██████▌   | 821/1261 [13:04<06:18,  1.16it/s]
Lanes were detected
 65%|██████▌   | 822/1261 [13:05<06:17,  1.16it/s]
Lanes were detected
 65%|██████▌   | 823/1261 [13:06<06:15,  1.17it/s]
Lanes were detected
 65%|██████▌   | 824/1261 [13:07<06:16,  1.16it/s]
Lanes were detected
 65%|██████▌   | 825/1261 [13:08<06:14,  1.16it/s]
Lanes were detected
 66%|██████▌   | 826/1261 [13:08<06:13,  1.17it/s]
Lanes were detected
 66%|██████▌   | 827/1261 [13:09<06:08,  1.18it/s]
Lanes were detected
 66%|██████▌   | 828/1261 [13:10<06:04,  1.19it/s]
Lanes were detected
 66%|██████▌   | 829/1261 [13:11<06:02,  1.19it/s]
Lanes were detected
 66%|██████▌   | 830/1261 [13:12<05:59,  1.20it/s]
Lanes were detected
 66%|██████▌   | 831/1261 [13:13<05:58,  1.20it/s]
Lanes were detected
 66%|██████▌   | 832/1261 [13:13<05:56,  1.21it/s]
Lanes were detected
 66%|██████▌   | 833/1261 [13:14<05:55,  1.21it/s]
Lanes were detected
 66%|██████▌   | 834/1261 [13:15<05:54,  1.20it/s]
Lanes were detected
 66%|██████▌   | 835/1261 [13:16<05:52,  1.21it/s]
Lanes were detected
 66%|██████▋   | 836/1261 [13:17<05:57,  1.19it/s]
Lanes were detected
 66%|██████▋   | 837/1261 [13:18<05:58,  1.18it/s]
Lanes were detected
 66%|██████▋   | 838/1261 [13:18<05:54,  1.19it/s]
Lanes were detected
 67%|██████▋   | 839/1261 [13:19<05:51,  1.20it/s]
Lanes were detected
 67%|██████▋   | 840/1261 [13:20<05:50,  1.20it/s]
Lanes were detected
 67%|██████▋   | 841/1261 [13:21<05:52,  1.19it/s]
Lanes were detected
 67%|██████▋   | 842/1261 [13:22<05:49,  1.20it/s]
Lanes were detected
 67%|██████▋   | 843/1261 [13:23<05:46,  1.21it/s]
Lanes were detected
 67%|██████▋   | 844/1261 [13:23<05:44,  1.21it/s]
Lanes were detected
 67%|██████▋   | 845/1261 [13:24<05:43,  1.21it/s]
Lanes were detected
 67%|██████▋   | 846/1261 [13:25<05:42,  1.21it/s]
Lanes were detected
 67%|██████▋   | 847/1261 [13:26<05:40,  1.22it/s]
Lanes were detected
 67%|██████▋   | 848/1261 [13:27<05:40,  1.21it/s]
Lanes were detected
 67%|██████▋   | 849/1261 [13:28<05:39,  1.21it/s]
Lanes were detected
 67%|██████▋   | 850/1261 [13:28<05:40,  1.21it/s]
Lanes were detected
 67%|██████▋   | 851/1261 [13:29<05:39,  1.21it/s]
Lanes were detected
 68%|██████▊   | 852/1261 [13:30<05:38,  1.21it/s]
Lanes were detected
 68%|██████▊   | 853/1261 [13:31<05:38,  1.21it/s]
Lanes were detected
 68%|██████▊   | 854/1261 [13:32<05:44,  1.18it/s]
Lanes were detected
 68%|██████▊   | 855/1261 [13:33<05:41,  1.19it/s]
Lanes were detected
 68%|██████▊   | 856/1261 [13:33<05:42,  1.18it/s]
Lanes were detected
 68%|██████▊   | 857/1261 [13:34<05:40,  1.19it/s]
Lanes were detected
 68%|██████▊   | 858/1261 [13:35<05:38,  1.19it/s]
Lanes were detected
 68%|██████▊   | 859/1261 [13:36<05:37,  1.19it/s]
Lanes were detected
 68%|██████▊   | 860/1261 [13:37<05:37,  1.19it/s]
Lanes were detected
 68%|██████▊   | 861/1261 [13:38<05:36,  1.19it/s]
Lanes were detected
 68%|██████▊   | 862/1261 [13:39<05:35,  1.19it/s]
Lanes were detected
 68%|██████▊   | 863/1261 [13:39<05:36,  1.18it/s]
Lanes were detected
 69%|██████▊   | 864/1261 [13:40<05:36,  1.18it/s]
Lanes were detected
 69%|██████▊   | 865/1261 [13:41<05:41,  1.16it/s]
Lanes were detected
 69%|██████▊   | 866/1261 [13:42<05:49,  1.13it/s]
Lanes were detected
 69%|██████▉   | 867/1261 [13:43<05:50,  1.12it/s]
Lanes were detected
 69%|██████▉   | 868/1261 [13:44<05:48,  1.13it/s]
Lanes were detected
 69%|██████▉   | 869/1261 [13:45<05:55,  1.10it/s]
Lanes were detected
 69%|██████▉   | 870/1261 [13:46<06:22,  1.02it/s]
Lanes were detected
 69%|██████▉   | 871/1261 [13:47<06:22,  1.02it/s]
Lanes were detected
 69%|██████▉   | 872/1261 [13:48<06:26,  1.01it/s]
Lanes were detected
 69%|██████▉   | 873/1261 [13:49<06:48,  1.05s/it]
Lanes were detected
 69%|██████▉   | 874/1261 [13:50<06:54,  1.07s/it]
Lanes were detected
 69%|██████▉   | 875/1261 [13:51<06:53,  1.07s/it]
Lanes were detected
 69%|██████▉   | 876/1261 [13:52<06:44,  1.05s/it]
Lanes were detected
 70%|██████▉   | 877/1261 [13:53<06:45,  1.06s/it]
Lanes were detected
 70%|██████▉   | 878/1261 [13:54<06:45,  1.06s/it]
Lanes were detected
 70%|██████▉   | 879/1261 [13:56<06:53,  1.08s/it]
Lanes were detected
 70%|██████▉   | 880/1261 [13:57<07:06,  1.12s/it]
Lanes were detected
 70%|██████▉   | 881/1261 [13:58<07:26,  1.18s/it]
Lanes were detected
 70%|██████▉   | 882/1261 [13:59<07:12,  1.14s/it]
Lanes were detected
 70%|███████   | 883/1261 [14:00<07:02,  1.12s/it]
Lanes were detected
 70%|███████   | 884/1261 [14:01<06:53,  1.10s/it]
Lanes were detected
 70%|███████   | 885/1261 [14:02<06:24,  1.02s/it]
Lanes were detected
 70%|███████   | 886/1261 [14:03<06:07,  1.02it/s]
Lanes were detected
 70%|███████   | 887/1261 [14:04<05:48,  1.07it/s]
Lanes weren't detected
 70%|███████   | 888/1261 [14:05<05:32,  1.12it/s]
Lanes weren't detected
 70%|███████   | 889/1261 [14:05<05:24,  1.15it/s]
Lanes weren't detected
 71%|███████   | 890/1261 [14:06<05:18,  1.16it/s]
Lanes weren't detected
 71%|███████   | 891/1261 [14:07<05:16,  1.17it/s]
Lanes were detected
 71%|███████   | 892/1261 [14:08<06:02,  1.02it/s]
Lanes weren't detected
 71%|███████   | 893/1261 [14:10<06:19,  1.03s/it]
Lanes were detected
 71%|███████   | 894/1261 [14:11<06:59,  1.14s/it]
Lanes weren't detected
 71%|███████   | 895/1261 [14:12<07:20,  1.20s/it]
Lanes weren't detected
 71%|███████   | 896/1261 [14:14<07:27,  1.23s/it]
Lanes weren't detected
 71%|███████   | 897/1261 [14:15<07:12,  1.19s/it]
Lanes weren't detected
 71%|███████   | 898/1261 [14:16<07:22,  1.22s/it]
Lanes weren't detected
 71%|███████▏  | 899/1261 [14:17<07:15,  1.20s/it]
Lanes weren't detected
 71%|███████▏  | 900/1261 [14:18<07:19,  1.22s/it]
Lanes weren't detected
 71%|███████▏  | 901/1261 [14:19<06:59,  1.17s/it]
Lanes weren't detected
 72%|███████▏  | 902/1261 [14:20<06:45,  1.13s/it]
Lanes weren't detected
 72%|███████▏  | 903/1261 [14:21<06:34,  1.10s/it]
Lanes weren't detected
 72%|███████▏  | 904/1261 [14:23<06:23,  1.07s/it]
Lanes were detected
 72%|███████▏  | 905/1261 [14:24<06:14,  1.05s/it]
Lanes weren't detected
 72%|███████▏  | 906/1261 [14:25<06:10,  1.04s/it]
Lanes weren't detected
 72%|███████▏  | 907/1261 [14:26<06:03,  1.03s/it]
Lanes weren't detected
 72%|███████▏  | 908/1261 [14:27<06:00,  1.02s/it]
Lanes weren't detected
 72%|███████▏  | 909/1261 [14:28<06:01,  1.03s/it]
Lanes weren't detected
 72%|███████▏  | 910/1261 [14:29<05:57,  1.02s/it]
Lanes weren't detected
 72%|███████▏  | 911/1261 [14:30<05:57,  1.02s/it]
Lanes weren't detected
 72%|███████▏  | 912/1261 [14:31<05:55,  1.02s/it]
Lanes weren't detected
 72%|███████▏  | 913/1261 [14:32<05:55,  1.02s/it]
Lanes weren't detected
 72%|███████▏  | 914/1261 [14:33<05:53,  1.02s/it]
Lanes weren't detected
 73%|███████▎  | 915/1261 [14:34<05:49,  1.01s/it]
Lanes weren't detected
 73%|███████▎  | 916/1261 [14:35<05:49,  1.01s/it]
Lanes weren't detected
 73%|███████▎  | 917/1261 [14:36<05:46,  1.01s/it]
Lanes weren't detected
 73%|███████▎  | 918/1261 [14:37<05:46,  1.01s/it]
Lanes weren't detected
 73%|███████▎  | 919/1261 [14:38<05:50,  1.02s/it]
Lanes weren't detected
 73%|███████▎  | 920/1261 [14:39<05:48,  1.02s/it]
Lanes weren't detected
 73%|███████▎  | 921/1261 [14:40<05:46,  1.02s/it]
Lanes weren't detected
 73%|███████▎  | 922/1261 [14:41<05:41,  1.01s/it]
Lanes weren't detected
 73%|███████▎  | 923/1261 [14:42<05:45,  1.02s/it]
Lanes weren't detected
 73%|███████▎  | 924/1261 [14:43<05:44,  1.02s/it]
Lanes weren't detected
 73%|███████▎  | 925/1261 [14:44<05:48,  1.04s/it]
Lanes weren't detected
 73%|███████▎  | 926/1261 [14:45<05:48,  1.04s/it]
Lanes weren't detected
 74%|███████▎  | 927/1261 [14:46<05:47,  1.04s/it]
Lanes weren't detected
 74%|███████▎  | 928/1261 [14:47<05:46,  1.04s/it]
Lanes weren't detected
 74%|███████▎  | 929/1261 [14:48<05:45,  1.04s/it]
Lanes weren't detected
 74%|███████▍  | 930/1261 [14:49<05:40,  1.03s/it]
Lanes weren't detected
 74%|███████▍  | 931/1261 [14:50<05:39,  1.03s/it]
Lanes weren't detected
 74%|███████▍  | 932/1261 [14:51<05:38,  1.03s/it]
Lanes weren't detected
 74%|███████▍  | 933/1261 [14:52<05:36,  1.03s/it]
Lanes weren't detected
 74%|███████▍  | 934/1261 [14:53<05:34,  1.02s/it]
Lanes weren't detected
 74%|███████▍  | 935/1261 [14:54<05:32,  1.02s/it]
Lanes weren't detected
 74%|███████▍  | 936/1261 [14:55<05:34,  1.03s/it]
Lanes weren't detected
 74%|███████▍  | 937/1261 [14:56<05:31,  1.02s/it]
Lanes weren't detected
 74%|███████▍  | 938/1261 [14:57<05:32,  1.03s/it]
Lanes were detected
 74%|███████▍  | 939/1261 [14:58<05:28,  1.02s/it]
Lanes weren't detected
 75%|███████▍  | 940/1261 [14:59<05:19,  1.00it/s]
Lanes weren't detected
 75%|███████▍  | 941/1261 [15:00<05:03,  1.05it/s]
Lanes weren't detected
 75%|███████▍  | 942/1261 [15:01<04:53,  1.09it/s]
Lanes weren't detected
 75%|███████▍  | 943/1261 [15:02<04:44,  1.12it/s]
Lanes weren't detected
 75%|███████▍  | 944/1261 [15:03<04:39,  1.13it/s]
Lanes weren't detected
 75%|███████▍  | 945/1261 [15:03<04:38,  1.13it/s]
Lanes weren't detected
 75%|███████▌  | 946/1261 [15:04<04:38,  1.13it/s]
Lanes weren't detected
 75%|███████▌  | 947/1261 [15:05<04:37,  1.13it/s]
Lanes weren't detected
 75%|███████▌  | 948/1261 [15:06<04:36,  1.13it/s]
Lanes weren't detected
 75%|███████▌  | 949/1261 [15:07<04:34,  1.14it/s]
Lanes weren't detected
 75%|███████▌  | 950/1261 [15:08<04:33,  1.14it/s]
Lanes were detected
 75%|███████▌  | 951/1261 [15:09<04:32,  1.14it/s]
Lanes weren't detected
 75%|███████▌  | 952/1261 [15:10<04:31,  1.14it/s]
Lanes weren't detected
 76%|███████▌  | 953/1261 [15:10<04:29,  1.14it/s]
Lanes weren't detected
 76%|███████▌  | 954/1261 [15:11<04:29,  1.14it/s]
Lanes weren't detected
 76%|███████▌  | 955/1261 [15:12<04:31,  1.13it/s]
Lanes weren't detected
 76%|███████▌  | 956/1261 [15:13<04:46,  1.06it/s]
Lanes weren't detected
 76%|███████▌  | 957/1261 [15:14<04:54,  1.03it/s]
Lanes weren't detected
 76%|███████▌  | 958/1261 [15:15<05:02,  1.00it/s]
Lanes weren't detected
 76%|███████▌  | 959/1261 [15:16<05:00,  1.00it/s]
Lanes weren't detected
 76%|███████▌  | 960/1261 [15:18<05:06,  1.02s/it]
Lanes weren't detected
 76%|███████▌  | 961/1261 [15:19<05:08,  1.03s/it]
Lanes were detected
 76%|███████▋  | 962/1261 [15:20<05:15,  1.06s/it]
Lanes were detected
 76%|███████▋  | 963/1261 [15:21<05:58,  1.20s/it]
Lanes weren't detected
 76%|███████▋  | 964/1261 [15:22<05:45,  1.16s/it]
Lanes weren't detected
 77%|███████▋  | 965/1261 [15:23<05:38,  1.14s/it]
Lanes were detected
 77%|███████▋  | 966/1261 [15:25<05:46,  1.17s/it]
Lanes weren't detected
 77%|███████▋  | 967/1261 [15:26<05:42,  1.16s/it]
Lanes weren't detected
 77%|███████▋  | 968/1261 [15:27<05:39,  1.16s/it]
Lanes weren't detected
 77%|███████▋  | 969/1261 [15:28<05:34,  1.14s/it]
Lanes weren't detected
 77%|███████▋  | 970/1261 [15:29<05:43,  1.18s/it]
Lanes weren't detected
 77%|███████▋  | 971/1261 [15:31<05:51,  1.21s/it]
Lanes weren't detected
 77%|███████▋  | 972/1261 [15:32<05:38,  1.17s/it]
Lanes weren't detected
 77%|███████▋  | 973/1261 [15:33<05:17,  1.10s/it]
Lanes weren't detected
 77%|███████▋  | 974/1261 [15:34<05:04,  1.06s/it]
Lanes weren't detected
 77%|███████▋  | 975/1261 [15:35<04:52,  1.02s/it]
Lanes weren't detected
 77%|███████▋  | 976/1261 [15:35<04:47,  1.01s/it]
Lanes weren't detected
 77%|███████▋  | 977/1261 [15:36<04:42,  1.01it/s]
Lanes weren't detected
 78%|███████▊  | 978/1261 [15:37<04:34,  1.03it/s]
Lanes weren't detected
 78%|███████▊  | 979/1261 [15:38<04:42,  1.00s/it]
Lanes weren't detected
 78%|███████▊  | 980/1261 [15:39<04:34,  1.02it/s]
Lanes weren't detected
 78%|███████▊  | 981/1261 [15:40<04:29,  1.04it/s]
Lanes weren't detected
 78%|███████▊  | 982/1261 [15:41<04:25,  1.05it/s]
Lanes weren't detected
 78%|███████▊  | 983/1261 [15:42<04:23,  1.06it/s]
Lanes weren't detected
 78%|███████▊  | 984/1261 [15:43<04:18,  1.07it/s]
Lanes weren't detected
 78%|███████▊  | 985/1261 [15:44<04:15,  1.08it/s]
Lanes weren't detected
 78%|███████▊  | 986/1261 [15:45<04:11,  1.10it/s]
Lanes weren't detected
 78%|███████▊  | 987/1261 [15:46<04:07,  1.11it/s]
Lanes weren't detected
 78%|███████▊  | 988/1261 [15:47<04:08,  1.10it/s]
Lanes weren't detected
 78%|███████▊  | 989/1261 [15:48<04:08,  1.10it/s]
Lanes weren't detected
 79%|███████▊  | 990/1261 [15:48<04:04,  1.11it/s]
Lanes weren't detected
 79%|███████▊  | 991/1261 [15:49<04:04,  1.10it/s]
Lanes weren't detected
 79%|███████▊  | 992/1261 [15:50<04:04,  1.10it/s]
Lanes weren't detected
 79%|███████▊  | 993/1261 [15:51<04:01,  1.11it/s]
Lanes weren't detected
 79%|███████▉  | 994/1261 [15:52<04:01,  1.11it/s]
Lanes weren't detected
 79%|███████▉  | 995/1261 [15:53<04:00,  1.11it/s]
Lanes weren't detected
 79%|███████▉  | 996/1261 [15:54<04:01,  1.10it/s]
Lanes weren't detected
 79%|███████▉  | 997/1261 [15:55<04:00,  1.10it/s]
Lanes weren't detected
 79%|███████▉  | 998/1261 [15:56<04:00,  1.09it/s]
Lanes weren't detected
 79%|███████▉  | 999/1261 [15:57<03:56,  1.11it/s]
Lanes weren't detected
 79%|███████▉  | 1000/1261 [15:58<03:55,  1.11it/s]
Lanes weren't detected
 79%|███████▉  | 1001/1261 [15:58<03:53,  1.11it/s]
Lanes weren't detected
 79%|███████▉  | 1002/1261 [15:59<03:54,  1.10it/s]
Lanes weren't detected
 80%|███████▉  | 1003/1261 [16:00<03:53,  1.10it/s]
Lanes were detected
 80%|███████▉  | 1004/1261 [16:01<03:55,  1.09it/s]
Lanes were detected
 80%|███████▉  | 1005/1261 [16:02<03:52,  1.10it/s]
Lanes were detected
 80%|███████▉  | 1006/1261 [16:03<03:52,  1.10it/s]
Lanes were detected
 80%|███████▉  | 1007/1261 [16:04<03:53,  1.09it/s]
Lanes were detected
 80%|███████▉  | 1008/1261 [16:05<03:52,  1.09it/s]
Lanes were detected
 80%|████████  | 1009/1261 [16:06<03:49,  1.10it/s]
Lanes were detected
 80%|████████  | 1010/1261 [16:07<03:48,  1.10it/s]
Lanes were detected
 80%|████████  | 1011/1261 [16:08<03:47,  1.10it/s]
Lanes were detected
 80%|████████  | 1012/1261 [16:09<04:03,  1.02it/s]
Lanes were detected
 80%|████████  | 1013/1261 [16:10<03:59,  1.04it/s]
Lanes were detected
 80%|████████  | 1014/1261 [16:11<04:00,  1.03it/s]
Lanes were detected
 80%|████████  | 1015/1261 [16:12<03:59,  1.03it/s]
Lanes were detected
 81%|████████  | 1016/1261 [16:13<03:56,  1.04it/s]
Lanes were detected
 81%|████████  | 1017/1261 [16:13<03:48,  1.07it/s]
Lanes were detected
 81%|████████  | 1018/1261 [16:14<03:43,  1.09it/s]
Lanes were detected
 81%|████████  | 1019/1261 [16:15<03:38,  1.11it/s]
Lanes were detected
 81%|████████  | 1020/1261 [16:16<03:35,  1.12it/s]
Lanes were detected
 81%|████████  | 1021/1261 [16:17<03:33,  1.13it/s]
Lanes were detected
 81%|████████  | 1022/1261 [16:18<03:32,  1.13it/s]
Lanes were detected
 81%|████████  | 1023/1261 [16:19<03:29,  1.13it/s]
Lanes were detected
 81%|████████  | 1024/1261 [16:20<03:27,  1.14it/s]
Lanes were detected
 81%|████████▏ | 1025/1261 [16:20<03:25,  1.15it/s]
Lanes were detected
 81%|████████▏ | 1026/1261 [16:21<03:21,  1.17it/s]
Lanes were detected
 81%|████████▏ | 1027/1261 [16:22<03:16,  1.19it/s]
Lanes were detected
 82%|████████▏ | 1028/1261 [16:23<03:15,  1.19it/s]
Lanes were detected
 82%|████████▏ | 1029/1261 [16:24<03:15,  1.18it/s]
Lanes were detected
 82%|████████▏ | 1030/1261 [16:25<03:16,  1.17it/s]
Lanes were detected
 82%|████████▏ | 1031/1261 [16:26<03:22,  1.13it/s]
Lanes were detected
 82%|████████▏ | 1032/1261 [16:27<03:39,  1.04it/s]
Lanes were detected
 82%|████████▏ | 1033/1261 [16:28<03:49,  1.01s/it]
Lanes were detected
 82%|████████▏ | 1034/1261 [16:29<03:52,  1.02s/it]
Lanes were detected
 82%|████████▏ | 1035/1261 [16:30<03:46,  1.00s/it]
Lanes were detected
 82%|████████▏ | 1036/1261 [16:31<03:43,  1.01it/s]
Lanes were detected
 82%|████████▏ | 1037/1261 [16:32<03:40,  1.02it/s]
Lanes were detected
 82%|████████▏ | 1038/1261 [16:33<03:34,  1.04it/s]
Lanes were detected
 82%|████████▏ | 1039/1261 [16:34<03:30,  1.06it/s]
Lanes were detected
 82%|████████▏ | 1040/1261 [16:34<03:27,  1.07it/s]
Lanes were detected
 83%|████████▎ | 1041/1261 [16:35<03:26,  1.06it/s]
Lanes were detected
 83%|████████▎ | 1042/1261 [16:36<03:25,  1.07it/s]
Lanes were detected
 83%|████████▎ | 1043/1261 [16:37<03:25,  1.06it/s]
Lanes were detected
 83%|████████▎ | 1044/1261 [16:38<03:24,  1.06it/s]
Lanes were detected
 83%|████████▎ | 1045/1261 [16:39<03:24,  1.06it/s]
Lanes were detected
 83%|████████▎ | 1046/1261 [16:40<03:20,  1.07it/s]
Lanes were detected
 83%|████████▎ | 1047/1261 [16:41<03:20,  1.07it/s]
Lanes were detected
 83%|████████▎ | 1048/1261 [16:42<03:27,  1.03it/s]
Lanes were detected
 83%|████████▎ | 1049/1261 [16:43<03:25,  1.03it/s]
Lanes were detected
 83%|████████▎ | 1050/1261 [16:44<03:20,  1.05it/s]
Lanes were detected
 83%|████████▎ | 1051/1261 [16:45<03:16,  1.07it/s]
Lanes were detected
 83%|████████▎ | 1052/1261 [16:46<03:11,  1.09it/s]
Lanes were detected
 84%|████████▎ | 1053/1261 [16:47<03:09,  1.10it/s]
Lanes were detected
 84%|████████▎ | 1054/1261 [16:48<03:08,  1.10it/s]
Lanes were detected
 84%|████████▎ | 1055/1261 [16:48<03:06,  1.10it/s]
Lanes were detected
 84%|████████▎ | 1056/1261 [16:49<03:11,  1.07it/s]
Lanes were detected
 84%|████████▍ | 1057/1261 [16:50<03:11,  1.07it/s]
Lanes were detected
 84%|████████▍ | 1058/1261 [16:51<03:10,  1.07it/s]
Lanes were detected
 84%|████████▍ | 1059/1261 [16:53<03:28,  1.03s/it]
Lanes were detected
 84%|████████▍ | 1060/1261 [16:54<03:29,  1.04s/it]
Lanes were detected
 84%|████████▍ | 1061/1261 [16:56<04:20,  1.30s/it]
Lanes were detected
 84%|████████▍ | 1062/1261 [16:57<04:40,  1.41s/it]
Lanes were detected
 84%|████████▍ | 1063/1261 [16:58<04:14,  1.29s/it]
Lanes were detected
 84%|████████▍ | 1064/1261 [16:59<03:52,  1.18s/it]
Lanes were detected
 84%|████████▍ | 1065/1261 [17:00<03:34,  1.09s/it]
Lanes were detected
 85%|████████▍ | 1066/1261 [17:01<03:28,  1.07s/it]
Lanes were detected
 85%|████████▍ | 1067/1261 [17:02<03:35,  1.11s/it]
Lanes were detected
 85%|████████▍ | 1068/1261 [17:03<03:36,  1.12s/it]
Lanes were detected
 85%|████████▍ | 1069/1261 [17:05<03:52,  1.21s/it]
Lanes were detected
 85%|████████▍ | 1070/1261 [17:06<04:17,  1.35s/it]
Lanes were detected
 85%|████████▍ | 1071/1261 [17:07<03:47,  1.20s/it]
Lanes were detected
 85%|████████▌ | 1072/1261 [17:08<03:40,  1.16s/it]
Lanes were detected
 85%|████████▌ | 1073/1261 [17:10<03:41,  1.18s/it]
Lanes were detected
 85%|████████▌ | 1074/1261 [17:11<03:37,  1.16s/it]
Lanes were detected
 85%|████████▌ | 1075/1261 [17:12<03:32,  1.14s/it]
Lanes were detected
 85%|████████▌ | 1076/1261 [17:13<03:26,  1.12s/it]
Lanes were detected
 85%|████████▌ | 1077/1261 [17:14<03:14,  1.06s/it]
Lanes were detected
 85%|████████▌ | 1078/1261 [17:15<03:05,  1.01s/it]
Lanes were detected
 86%|████████▌ | 1079/1261 [17:16<02:58,  1.02it/s]
Lanes were detected
 86%|████████▌ | 1080/1261 [17:17<02:53,  1.04it/s]
Lanes were detected
 86%|████████▌ | 1081/1261 [17:17<02:45,  1.09it/s]
Lanes were detected
 86%|████████▌ | 1082/1261 [17:18<02:41,  1.11it/s]
Lanes were detected
 86%|████████▌ | 1083/1261 [17:19<02:38,  1.12it/s]
Lanes were detected
 86%|████████▌ | 1084/1261 [17:20<02:37,  1.13it/s]
Lanes were detected
 86%|████████▌ | 1085/1261 [17:21<02:36,  1.13it/s]
Lanes were detected
 86%|████████▌ | 1086/1261 [17:22<02:36,  1.12it/s]
Lanes were detected
 86%|████████▌ | 1087/1261 [17:23<02:35,  1.12it/s]
Lanes were detected
 86%|████████▋ | 1088/1261 [17:24<02:32,  1.13it/s]
Lanes were detected
 86%|████████▋ | 1089/1261 [17:24<02:29,  1.15it/s]
Lanes were detected
 86%|████████▋ | 1090/1261 [17:25<02:30,  1.14it/s]
Lanes were detected
 87%|████████▋ | 1091/1261 [17:26<02:34,  1.10it/s]
Lanes were detected
 87%|████████▋ | 1092/1261 [17:27<02:34,  1.09it/s]
Lanes were detected
 87%|████████▋ | 1093/1261 [17:28<02:34,  1.09it/s]
Lanes were detected
 87%|████████▋ | 1094/1261 [17:29<02:35,  1.07it/s]
Lanes were detected
 87%|████████▋ | 1095/1261 [17:30<02:33,  1.08it/s]
Lanes were detected
 87%|████████▋ | 1096/1261 [17:31<02:31,  1.09it/s]
Lanes were detected
 87%|████████▋ | 1097/1261 [17:32<02:30,  1.09it/s]
Lanes were detected
 87%|████████▋ | 1098/1261 [17:33<02:25,  1.12it/s]
Lanes were detected
 87%|████████▋ | 1099/1261 [17:34<02:28,  1.09it/s]
Lanes were detected
 87%|████████▋ | 1100/1261 [17:34<02:24,  1.11it/s]
Lanes were detected
 87%|████████▋ | 1101/1261 [17:35<02:21,  1.13it/s]
Lanes were detected
 87%|████████▋ | 1102/1261 [17:36<02:20,  1.13it/s]
Lanes were detected
 87%|████████▋ | 1103/1261 [17:37<02:19,  1.13it/s]
Lanes were detected
 88%|████████▊ | 1104/1261 [17:38<02:18,  1.14it/s]
Lanes were detected
 88%|████████▊ | 1105/1261 [17:39<02:16,  1.14it/s]
Lanes were detected
 88%|████████▊ | 1106/1261 [17:40<02:14,  1.15it/s]
Lanes were detected
 88%|████████▊ | 1107/1261 [17:41<02:13,  1.16it/s]
Lanes were detected
 88%|████████▊ | 1108/1261 [17:41<02:11,  1.16it/s]
Lanes were detected
 88%|████████▊ | 1109/1261 [17:42<02:10,  1.17it/s]
Lanes were detected
 88%|████████▊ | 1110/1261 [17:43<02:09,  1.17it/s]
Lanes were detected
 88%|████████▊ | 1111/1261 [17:44<02:10,  1.15it/s]
Lanes were detected
 88%|████████▊ | 1112/1261 [17:45<02:10,  1.14it/s]
Lanes were detected
 88%|████████▊ | 1113/1261 [17:46<02:13,  1.11it/s]
Lanes were detected
 88%|████████▊ | 1114/1261 [17:47<02:12,  1.11it/s]
Lanes were detected
 88%|████████▊ | 1115/1261 [17:48<02:12,  1.11it/s]
Lanes were detected
 89%|████████▊ | 1116/1261 [17:49<02:10,  1.11it/s]
Lanes were detected
 89%|████████▊ | 1117/1261 [17:49<02:11,  1.10it/s]
Lanes were detected
 89%|████████▊ | 1118/1261 [17:50<02:10,  1.09it/s]
Lanes were detected
 89%|████████▊ | 1119/1261 [17:51<02:11,  1.08it/s]
Lanes were detected
 89%|████████▉ | 1120/1261 [17:52<02:08,  1.09it/s]
Lanes were detected
 89%|████████▉ | 1121/1261 [17:53<02:05,  1.12it/s]
Lanes were detected
 89%|████████▉ | 1122/1261 [17:54<02:02,  1.14it/s]
Lanes were detected
 89%|████████▉ | 1123/1261 [17:55<02:03,  1.12it/s]
Lanes were detected
 89%|████████▉ | 1124/1261 [17:56<02:05,  1.09it/s]
Lanes were detected
 89%|████████▉ | 1125/1261 [17:57<02:04,  1.09it/s]
Lanes were detected
 89%|████████▉ | 1126/1261 [17:58<02:04,  1.08it/s]
Lanes were detected
 89%|████████▉ | 1127/1261 [17:59<02:01,  1.10it/s]
Lanes were detected
 89%|████████▉ | 1128/1261 [17:59<01:58,  1.12it/s]
Lanes were detected
 90%|████████▉ | 1129/1261 [18:00<01:55,  1.15it/s]
Lanes were detected
 90%|████████▉ | 1130/1261 [18:01<01:53,  1.15it/s]
Lanes were detected
 90%|████████▉ | 1131/1261 [18:02<01:56,  1.12it/s]
Lanes were detected
 90%|████████▉ | 1132/1261 [18:03<02:00,  1.07it/s]
Lanes were detected
 90%|████████▉ | 1133/1261 [18:04<01:58,  1.08it/s]
Lanes were detected
 90%|████████▉ | 1134/1261 [18:05<02:06,  1.00it/s]
Lanes were detected
 90%|█████████ | 1135/1261 [18:06<02:11,  1.05s/it]
Lanes were detected
 90%|█████████ | 1136/1261 [18:08<02:17,  1.10s/it]
Lanes were detected
 90%|█████████ | 1137/1261 [18:09<02:12,  1.07s/it]
Lanes were detected
 90%|█████████ | 1138/1261 [18:10<02:18,  1.13s/it]
Lanes were detected
 90%|█████████ | 1139/1261 [18:11<02:19,  1.14s/it]
Lanes were detected
 90%|█████████ | 1140/1261 [18:12<02:17,  1.14s/it]
Lanes were detected
 90%|█████████ | 1141/1261 [18:13<02:14,  1.12s/it]
Lanes were detected
 91%|█████████ | 1142/1261 [18:14<02:11,  1.11s/it]
Lanes were detected
 91%|█████████ | 1143/1261 [18:15<02:07,  1.08s/it]
Lanes were detected
 91%|█████████ | 1144/1261 [18:16<02:00,  1.03s/it]
Lanes were detected
 91%|█████████ | 1145/1261 [18:17<01:55,  1.00it/s]
Lanes were detected
 91%|█████████ | 1146/1261 [18:18<01:53,  1.01it/s]
Lanes were detected
 91%|█████████ | 1147/1261 [18:19<01:51,  1.02it/s]
Lanes were detected
 91%|█████████ | 1148/1261 [18:20<01:50,  1.02it/s]
Lanes were detected
 91%|█████████ | 1149/1261 [18:21<01:49,  1.02it/s]
Lanes were detected
 91%|█████████ | 1150/1261 [18:22<01:46,  1.04it/s]
Lanes were detected
 91%|█████████▏| 1151/1261 [18:23<01:45,  1.05it/s]
Lanes were detected
 91%|█████████▏| 1152/1261 [18:24<01:43,  1.05it/s]
Lanes were detected
 91%|█████████▏| 1153/1261 [18:25<01:41,  1.06it/s]
Lanes were detected
 92%|█████████▏| 1154/1261 [18:26<01:41,  1.05it/s]
Lanes were detected
 92%|█████████▏| 1155/1261 [18:27<01:38,  1.07it/s]
Lanes were detected
 92%|█████████▏| 1156/1261 [18:27<01:37,  1.08it/s]
Lanes were detected
 92%|█████████▏| 1157/1261 [18:28<01:34,  1.10it/s]
Lanes were detected
 92%|█████████▏| 1158/1261 [18:29<01:33,  1.10it/s]
Lanes were detected
 92%|█████████▏| 1159/1261 [18:30<01:32,  1.10it/s]
Lanes were detected
 92%|█████████▏| 1160/1261 [18:31<01:32,  1.09it/s]
Lanes were detected
 92%|█████████▏| 1161/1261 [18:32<01:30,  1.10it/s]
Lanes were detected
 92%|█████████▏| 1162/1261 [18:33<01:30,  1.10it/s]
Lanes were detected
 92%|█████████▏| 1163/1261 [18:34<01:28,  1.11it/s]
Lanes were detected
 92%|█████████▏| 1164/1261 [18:35<01:27,  1.11it/s]
Lanes were detected
 92%|█████████▏| 1165/1261 [18:36<01:25,  1.12it/s]
Lanes were detected
 92%|█████████▏| 1166/1261 [18:36<01:24,  1.12it/s]
Lanes were detected
 93%|█████████▎| 1167/1261 [18:37<01:24,  1.11it/s]
Lanes were detected
 93%|█████████▎| 1168/1261 [18:38<01:23,  1.11it/s]
Lanes were detected
 93%|█████████▎| 1169/1261 [18:39<01:21,  1.12it/s]
Lanes were detected
 93%|█████████▎| 1170/1261 [18:40<01:22,  1.11it/s]
Lanes were detected
 93%|█████████▎| 1171/1261 [18:41<01:22,  1.10it/s]
Lanes were detected
 93%|█████████▎| 1172/1261 [18:42<01:20,  1.10it/s]
Lanes were detected
 93%|█████████▎| 1173/1261 [18:43<01:20,  1.10it/s]
Lanes were detected
 93%|█████████▎| 1174/1261 [18:44<01:18,  1.11it/s]
Lanes were detected
 93%|█████████▎| 1175/1261 [18:45<01:16,  1.12it/s]
Lanes were detected
 93%|█████████▎| 1176/1261 [18:45<01:16,  1.11it/s]
Lanes were detected
 93%|█████████▎| 1177/1261 [18:46<01:16,  1.09it/s]
Lanes were detected
 93%|█████████▎| 1178/1261 [18:47<01:15,  1.10it/s]
Lanes were detected
 93%|█████████▎| 1179/1261 [18:48<01:14,  1.09it/s]
Lanes were detected
 94%|█████████▎| 1180/1261 [18:49<01:14,  1.09it/s]
Lanes were detected
 94%|█████████▎| 1181/1261 [18:50<01:12,  1.10it/s]
Lanes were detected
 94%|█████████▎| 1182/1261 [18:51<01:11,  1.10it/s]
Lanes were detected
 94%|█████████▍| 1183/1261 [18:52<01:10,  1.11it/s]
Lanes were detected
 94%|█████████▍| 1184/1261 [18:53<01:09,  1.10it/s]
Lanes were detected
 94%|█████████▍| 1185/1261 [18:54<01:09,  1.10it/s]
Lanes were detected
 94%|█████████▍| 1186/1261 [18:55<01:08,  1.09it/s]
Lanes were detected
 94%|█████████▍| 1187/1261 [18:56<01:07,  1.09it/s]
Lanes were detected
 94%|█████████▍| 1188/1261 [18:56<01:07,  1.09it/s]
Lanes were detected
 94%|█████████▍| 1189/1261 [18:57<01:05,  1.10it/s]
Lanes were detected
 94%|█████████▍| 1190/1261 [18:58<01:03,  1.11it/s]
Lanes were detected
 94%|█████████▍| 1191/1261 [18:59<01:03,  1.11it/s]
Lanes were detected
 95%|█████████▍| 1192/1261 [19:00<01:02,  1.10it/s]
Lanes were detected
 95%|█████████▍| 1193/1261 [19:01<01:01,  1.10it/s]
Lanes were detected
 95%|█████████▍| 1194/1261 [19:02<01:01,  1.10it/s]
Lanes were detected
 95%|█████████▍| 1195/1261 [19:03<00:59,  1.10it/s]
Lanes were detected
 95%|█████████▍| 1196/1261 [19:04<00:59,  1.09it/s]
Lanes were detected
 95%|█████████▍| 1197/1261 [19:05<00:58,  1.10it/s]
Lanes were detected
 95%|█████████▌| 1198/1261 [19:06<00:57,  1.09it/s]
Lanes were detected
 95%|█████████▌| 1199/1261 [19:06<00:56,  1.11it/s]
Lanes were detected
 95%|█████████▌| 1200/1261 [19:07<00:55,  1.10it/s]
Lanes were detected
 95%|█████████▌| 1201/1261 [19:08<00:55,  1.08it/s]
Lanes were detected
 95%|█████████▌| 1202/1261 [19:09<00:57,  1.02it/s]
Lanes were detected
 95%|█████████▌| 1203/1261 [19:10<00:57,  1.01it/s]
Lanes were detected
 95%|█████████▌| 1204/1261 [19:11<00:57,  1.02s/it]
Lanes were detected
 96%|█████████▌| 1205/1261 [19:13<00:57,  1.03s/it]
Lanes were detected
 96%|█████████▌| 1206/1261 [19:13<00:54,  1.00it/s]
Lanes were detected
 96%|█████████▌| 1207/1261 [19:14<00:51,  1.04it/s]
Lanes were detected
 96%|█████████▌| 1208/1261 [19:15<00:49,  1.07it/s]
Lanes were detected
 96%|█████████▌| 1209/1261 [19:16<00:47,  1.09it/s]
Lanes were detected
 96%|█████████▌| 1210/1261 [19:17<00:46,  1.11it/s]
Lanes were detected
 96%|█████████▌| 1211/1261 [19:18<00:44,  1.13it/s]
Lanes were detected
 96%|█████████▌| 1212/1261 [19:19<00:42,  1.15it/s]
Lanes were detected
 96%|█████████▌| 1213/1261 [19:20<00:41,  1.16it/s]
Lanes were detected
 96%|█████████▋| 1214/1261 [19:20<00:40,  1.16it/s]
Lanes were detected
 96%|█████████▋| 1215/1261 [19:21<00:39,  1.17it/s]
Lanes were detected
 96%|█████████▋| 1216/1261 [19:22<00:38,  1.17it/s]
Lanes were detected
 97%|█████████▋| 1217/1261 [19:23<00:37,  1.18it/s]
Lanes were detected
 97%|█████████▋| 1218/1261 [19:24<00:36,  1.18it/s]
Lanes were detected
 97%|█████████▋| 1219/1261 [19:25<00:35,  1.17it/s]
Lanes were detected
 97%|█████████▋| 1220/1261 [19:26<00:36,  1.13it/s]
Lanes were detected
 97%|█████████▋| 1221/1261 [19:27<00:37,  1.08it/s]
Lanes were detected
 97%|█████████▋| 1222/1261 [19:28<00:37,  1.04it/s]
Lanes were detected
 97%|█████████▋| 1223/1261 [19:29<00:36,  1.04it/s]
Lanes were detected
 97%|█████████▋| 1224/1261 [19:30<00:37,  1.01s/it]
Lanes were detected
 97%|█████████▋| 1225/1261 [19:31<00:35,  1.00it/s]
Lanes were detected
 97%|█████████▋| 1226/1261 [19:32<00:34,  1.03it/s]
Lanes were detected
 97%|█████████▋| 1227/1261 [19:33<00:35,  1.04s/it]
Lanes were detected
 97%|█████████▋| 1228/1261 [19:34<00:37,  1.15s/it]
Lanes were detected
 97%|█████████▋| 1229/1261 [19:36<00:38,  1.22s/it]
Lanes were detected
 98%|█████████▊| 1230/1261 [19:37<00:36,  1.17s/it]
Lanes were detected
 98%|█████████▊| 1231/1261 [19:38<00:35,  1.18s/it]
Lanes were detected
 98%|█████████▊| 1232/1261 [19:39<00:32,  1.12s/it]
Lanes were detected
 98%|█████████▊| 1233/1261 [19:40<00:29,  1.05s/it]
Lanes were detected
 98%|█████████▊| 1234/1261 [19:41<00:27,  1.04s/it]
Lanes were detected
 98%|█████████▊| 1235/1261 [19:42<00:25,  1.00it/s]
Lanes were detected
 98%|█████████▊| 1236/1261 [19:43<00:24,  1.03it/s]
Lanes were detected
 98%|█████████▊| 1237/1261 [19:44<00:23,  1.03it/s]
Lanes were detected
 98%|█████████▊| 1238/1261 [19:44<00:21,  1.06it/s]
Lanes were detected
 98%|█████████▊| 1239/1261 [19:45<00:20,  1.08it/s]
Lanes were detected
 98%|█████████▊| 1240/1261 [19:46<00:19,  1.10it/s]
Lanes were detected
 98%|█████████▊| 1241/1261 [19:47<00:18,  1.10it/s]
Lanes were detected
 98%|█████████▊| 1242/1261 [19:48<00:17,  1.11it/s]
Lanes were detected
 99%|█████████▊| 1243/1261 [19:49<00:16,  1.10it/s]
Lanes were detected
 99%|█████████▊| 1244/1261 [19:50<00:15,  1.09it/s]
Lanes were detected
 99%|█████████▊| 1245/1261 [19:51<00:14,  1.09it/s]
Lanes were detected
 99%|█████████▉| 1246/1261 [19:52<00:13,  1.10it/s]
Lanes were detected
 99%|█████████▉| 1247/1261 [19:53<00:12,  1.09it/s]
Lanes were detected
 99%|█████████▉| 1248/1261 [19:53<00:11,  1.09it/s]
Lanes were detected
 99%|█████████▉| 1249/1261 [19:54<00:11,  1.07it/s]
Lanes were detected
 99%|█████████▉| 1250/1261 [19:55<00:10,  1.08it/s]
Lanes were detected
 99%|█████████▉| 1251/1261 [19:56<00:09,  1.06it/s]
Lanes were detected
 99%|█████████▉| 1252/1261 [19:57<00:08,  1.07it/s]
Lanes were detected
 99%|█████████▉| 1253/1261 [19:58<00:07,  1.08it/s]
Lanes were detected
 99%|█████████▉| 1254/1261 [19:59<00:06,  1.09it/s]
Lanes were detected
100%|█████████▉| 1255/1261 [20:00<00:05,  1.10it/s]
Lanes were detected
100%|█████████▉| 1256/1261 [20:01<00:04,  1.10it/s]
Lanes were detected
100%|█████████▉| 1257/1261 [20:02<00:03,  1.09it/s]
Lanes were detected
100%|█████████▉| 1258/1261 [20:03<00:02,  1.09it/s]
Lanes were detected
100%|█████████▉| 1259/1261 [20:04<00:01,  1.10it/s]
Lanes were detected
100%|█████████▉| 1260/1261 [20:05<00:00,  1.10it/s]
Lanes were detected

[MoviePy] Done.
[MoviePy] >>>> Video ready: project_video_result.mp4 

CPU times: user 15min 18s, sys: 5min 4s, total: 20min 23s
Wall time: 20min 6s
In [ ]: